blob: 22029544fa91175d2072c5f259a7c7ff089987c4 [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef RUNTIME_VM_COMPILER_ASSEMBLER_OBJECT_POOL_BUILDER_H_
#define RUNTIME_VM_COMPILER_ASSEMBLER_OBJECT_POOL_BUILDER_H_
#include "platform/globals.h"
#include "vm/bitfield.h"
#include "vm/hash_map.h"
namespace dart {
class Object;
namespace compiler {
class ExternalLabel;
bool IsSameObject(const Object& a, const Object& b);
struct ObjectPoolBuilderEntry {
enum Patchability {
kPatchable,
kNotPatchable,
};
enum EntryType {
kTaggedObject,
kImmediate,
kNativeFunction,
kNativeFunctionWrapper,
kNativeEntryData,
};
using TypeBits = BitField<uint8_t, EntryType, 0, 7>;
using PatchableBit = BitField<uint8_t, Patchability, TypeBits::kNextBit, 1>;
static inline uint8_t EncodeTraits(EntryType type, Patchability patchable) {
return TypeBits::encode(type) | PatchableBit::encode(patchable);
}
ObjectPoolBuilderEntry() : raw_value_(), entry_bits_(0), equivalence_() {}
ObjectPoolBuilderEntry(const Object* obj, Patchability patchable)
: ObjectPoolBuilderEntry(obj, obj, patchable) {}
ObjectPoolBuilderEntry(const Object* obj,
const Object* eqv,
Patchability patchable)
: obj_(obj),
entry_bits_(EncodeTraits(kTaggedObject, patchable)),
equivalence_(eqv) {}
ObjectPoolBuilderEntry(uword value, EntryType info, Patchability patchable)
: raw_value_(value),
entry_bits_(EncodeTraits(info, patchable)),
equivalence_() {}
EntryType type() const { return TypeBits::decode(entry_bits_); }
Patchability patchable() const { return PatchableBit::decode(entry_bits_); }
union {
const Object* obj_;
uword raw_value_;
};
uint8_t entry_bits_;
const Object* equivalence_;
};
// Pair type parameter for DirectChainedHashMap used for the constant pool.
class ObjIndexPair {
public:
// Typedefs needed for the DirectChainedHashMap template.
typedef ObjectPoolBuilderEntry Key;
typedef intptr_t Value;
typedef ObjIndexPair Pair;
static const intptr_t kNoIndex = -1;
ObjIndexPair()
: key_(reinterpret_cast<uword>(nullptr),
ObjectPoolBuilderEntry::kTaggedObject,
ObjectPoolBuilderEntry::kPatchable),
value_(kNoIndex) {}
ObjIndexPair(Key key, Value value) : value_(value) {
key_.entry_bits_ = key.entry_bits_;
if (key.type() == ObjectPoolBuilderEntry::kTaggedObject) {
key_.obj_ = key.obj_;
key_.equivalence_ = key.equivalence_;
} else {
key_.raw_value_ = key.raw_value_;
}
}
static Key KeyOf(Pair kv) { return kv.key_; }
static Value ValueOf(Pair kv) { return kv.value_; }
static intptr_t Hashcode(Key key);
static inline bool IsKeyEqual(Pair kv, Key key) {
if (kv.key_.entry_bits_ != key.entry_bits_) return false;
if (kv.key_.type() == ObjectPoolBuilderEntry::kTaggedObject) {
return IsSameObject(*kv.key_.obj_, *key.obj_) &&
IsSameObject(*kv.key_.equivalence_, *key.equivalence_);
}
return kv.key_.raw_value_ == key.raw_value_;
}
private:
Key key_;
Value value_;
};
class ObjectPoolBuilder : public ValueObject {
public:
ObjectPoolBuilder() : zone_(nullptr) {}
~ObjectPoolBuilder() {
if (zone_ != nullptr) {
Reset();
zone_ = nullptr;
}
}
// Clears all existing entries in this object pool builder.
//
// Note: Any code which has been compiled via this builder might use offsets
// into the pool which are not correct anymore.
void Reset();
// Initialize this object pool builder with a [zone].
//
// Any objects added later on will be referenced using handles from [zone].
void InitializeWithZone(Zone* zone) {
ASSERT(object_pool_.length() == 0);
ASSERT(zone_ == nullptr && zone != nullptr);
zone_ = zone;
}
intptr_t AddObject(const Object& obj,
ObjectPoolBuilderEntry::Patchability patchable =
ObjectPoolBuilderEntry::kNotPatchable);
intptr_t AddImmediate(uword imm);
intptr_t FindObject(const Object& obj,
ObjectPoolBuilderEntry::Patchability patchable =
ObjectPoolBuilderEntry::kNotPatchable);
intptr_t FindObject(const Object& obj, const Object& equivalence);
intptr_t FindImmediate(uword imm);
intptr_t FindNativeFunction(const ExternalLabel* label,
ObjectPoolBuilderEntry::Patchability patchable);
intptr_t FindNativeFunctionWrapper(
const ExternalLabel* label,
ObjectPoolBuilderEntry::Patchability patchable);
intptr_t CurrentLength() const { return object_pool_.length(); }
ObjectPoolBuilderEntry& EntryAt(intptr_t i) { return object_pool_[i]; }
const ObjectPoolBuilderEntry& EntryAt(intptr_t i) const {
return object_pool_[i];
}
intptr_t AddObject(ObjectPoolBuilderEntry entry);
private:
intptr_t FindObject(ObjectPoolBuilderEntry entry);
// Objects and jump targets.
GrowableArray<ObjectPoolBuilderEntry> object_pool_;
// Hashmap for fast lookup in object pool.
DirectChainedHashMap<ObjIndexPair> object_pool_index_table_;
// The zone used for allocating the handles we keep in the map and array (or
// NULL, in which case allocations happen using the zone active at the point
// of insertion).
Zone* zone_;
};
} // namespace compiler
} // namespace dart
namespace dart {
using compiler::ObjectPoolBuilder;
}
#endif // RUNTIME_VM_COMPILER_ASSEMBLER_OBJECT_POOL_BUILDER_H_