Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index d95d307668ba37b42e9980ae11f4ba5dfb406bae..1abb2796dc0f13c3346d7bdebc4c8f000c9a9da7 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -94,6 +94,7 @@ Instance* Object::null_instance_ = NULL; |
TypeArguments* Object::null_type_arguments_ = NULL; |
Array* Object::empty_array_ = NULL; |
Array* Object::zero_array_ = NULL; |
+ObjectPool* Object::empty_object_pool_ = NULL; |
PcDescriptors* Object::empty_descriptors_ = NULL; |
LocalVarDescriptors* Object::empty_var_descriptors_ = NULL; |
ExceptionHandlers* Object::empty_exception_handlers_ = NULL; |
@@ -132,6 +133,7 @@ RawClass* Object::library_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::namespace_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::code_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
+RawClass* Object::object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::stackmap_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::var_descriptors_class_ = |
@@ -402,6 +404,7 @@ void Object::InitOnce(Isolate* isolate) { |
null_type_arguments_ = TypeArguments::ReadOnlyHandle(); |
empty_array_ = Array::ReadOnlyHandle(); |
zero_array_ = Array::ReadOnlyHandle(); |
+ empty_object_pool_ = ObjectPool::ReadOnlyHandle(); |
empty_descriptors_ = PcDescriptors::ReadOnlyHandle(); |
empty_var_descriptors_ = LocalVarDescriptors::ReadOnlyHandle(); |
empty_exception_handlers_ = ExceptionHandlers::ReadOnlyHandle(); |
@@ -543,6 +546,9 @@ void Object::InitOnce(Isolate* isolate) { |
cls = Class::New<Instructions>(); |
instructions_class_ = cls.raw(); |
+ cls = Class::New<ObjectPool>(); |
+ object_pool_class_ = cls.raw(); |
+ |
cls = Class::New<PcDescriptors>(); |
pc_descriptors_class_ = cls.raw(); |
@@ -635,6 +641,20 @@ void Object::InitOnce(Isolate* isolate) { |
zero_array_->SetAt(0, smi); |
} |
+ // Allocate and initialize the canonical empty object pool object. |
+ { |
+ uword address = |
+ heap->Allocate(ObjectPool::InstanceSize(0), Heap::kOld); |
+ InitializeObject(address, |
+ kObjectPoolCid, |
+ ObjectPool::InstanceSize(0)); |
+ ObjectPool::initializeHandle( |
+ empty_object_pool_, |
+ reinterpret_cast<RawObjectPool*>(address + kHeapObjectTag)); |
+ empty_object_pool_->StoreNonPointer( |
+ &empty_object_pool_->raw_ptr()->length_, 0); |
+ } |
+ |
// Allocate and initialize the empty_descriptors instance. |
{ |
uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld); |
@@ -821,6 +841,7 @@ void Object::FinalizeVMIsolate(Isolate* isolate) { |
SET_CLASS_NAME(namespace, Namespace); |
SET_CLASS_NAME(code, Code); |
SET_CLASS_NAME(instructions, Instructions); |
+ SET_CLASS_NAME(object_pool, ObjectPool); |
SET_CLASS_NAME(pc_descriptors, PcDescriptors); |
SET_CLASS_NAME(stackmap, Stackmap); |
SET_CLASS_NAME(var_descriptors, LocalVarDescriptors); |
@@ -3228,6 +3249,8 @@ RawString* Class::GenerateUserVisibleName() const { |
return Symbols::Code().raw(); |
case kInstructionsCid: |
return Symbols::Instructions().raw(); |
+ case kObjectPoolCid: |
+ return Symbols::ObjectPool().raw(); |
case kPcDescriptorsCid: |
return Symbols::PcDescriptors().raw(); |
case kStackmapCid: |
@@ -10662,6 +10685,70 @@ intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const { |
} |
+RawObjectPool* ObjectPool::New(intptr_t len) { |
+ ASSERT(Object::object_pool_class() != Class::null()); |
+ if (len < 0 || len > kMaxElements) { |
+ // This should be caught before we reach here. |
+ FATAL1("Fatal error in ObjectPool::New: invalid length %" Pd "\n", len); |
+ } |
+ ObjectPool& result = ObjectPool::Handle(); |
+ { |
+ uword size = ObjectPool::InstanceSize(len); |
+ RawObject* raw = Object::Allocate(ObjectPool::kClassId, |
+ size, |
+ Heap::kOld); |
+ NoSafepointScope no_safepoint; |
+ result ^= raw; |
+ result.SetLength(len); |
+ } |
+ const TypedData& info_array = TypedData::Handle( |
+ TypedData::New(kTypedDataInt8ArrayCid, len, Heap::kOld)); |
+ result.set_info_array(info_array); |
+ return result.raw(); |
+} |
+ |
+ |
+void ObjectPool::set_info_array(const TypedData& info_array) const { |
+ StorePointer(&raw_ptr()->info_array_, info_array.raw()); |
+} |
+ |
+ |
+ObjectPool::EntryType ObjectPool::InfoAt(intptr_t index) const { |
+ const TypedData& array = TypedData::Handle(info_array()); |
+ return static_cast<EntryType>(array.GetInt8(index)); |
+} |
+ |
+ |
+void ObjectPool::SetInfoAt(intptr_t index, EntryType info) const { |
+ const TypedData& array = TypedData::Handle(info_array()); |
+ array.SetInt8(index, static_cast<int8_t>(info)); |
+} |
+ |
+const char* ObjectPool::ToCString() const { |
+ return "ObjectPool"; |
+} |
+ |
+ |
+void ObjectPool::PrintJSONImpl(JSONStream* stream, bool ref) const { |
+ Object::PrintJSONImpl(stream, ref); |
+} |
+ |
+ |
+void ObjectPool::DebugPrint() const { |
+ ISL_Print("Object Pool: {\n"); |
+ for (intptr_t i = 0; i < Length(); i++) { |
+ if (InfoAt(i) == kTaggedObject) { |
+ ISL_Print(" %" Pd ": 0x%" Px " %s (obj)\n", i, |
+ reinterpret_cast<uword>(ObjectAt(i)), |
+ Object::Handle(ObjectAt(i)).ToCString()); |
+ } else { |
+ ISL_Print(" %" Pd ": 0x%" Px " (raw)\n", i, RawValueAt(i)); |
+ } |
+ } |
+ ISL_Print("}\n"); |
+} |
+ |
+ |
intptr_t PcDescriptors::Length() const { |
return raw_ptr()->length_; |
} |
@@ -12459,6 +12546,8 @@ RawCode* Code::FinalizeCode(const char* name, |
Assembler* assembler, |
bool optimized) { |
ASSERT(assembler != NULL); |
+ const ObjectPool& object_pool = |
+ ObjectPool::Handle(assembler->object_pool().MakeObjectPool()); |
// Allocate the Code and Instructions objects. Code is allocated first |
// because a GC during allocation of the code will leave the instruction |
@@ -12484,7 +12573,6 @@ RawCode* Code::FinalizeCode(const char* name, |
assembler->prologue_offset(), |
instrs.size(), |
optimized); |
- |
{ |
NoSafepointScope no_safepoint; |
const ZoneGrowableArray<intptr_t>& pointer_offsets = |
@@ -12509,17 +12597,10 @@ RawCode* Code::FinalizeCode(const char* name, |
code.set_is_alive(true); |
// Set object pool in Instructions object. |
- const GrowableObjectArray& object_pool = assembler->object_pool_data(); |
- if (object_pool.IsNull()) { |
- instrs.set_object_pool(Object::empty_array().raw()); |
- } else { |
- INC_STAT(Isolate::Current(), |
- total_code_size, object_pool.Length() * sizeof(uintptr_t)); |
- // TODO(regis): Once MakeArray takes a Heap::Space argument, call it here |
- // with Heap::kOld and change the ARM and MIPS assemblers to work with a |
- // GrowableObjectArray in new space. |
- instrs.set_object_pool(Array::MakeArray(object_pool)); |
- } |
+ INC_STAT(Isolate::Current(), |
+ total_code_size, object_pool.Length() * sizeof(uintptr_t)); |
+ instrs.set_object_pool(object_pool.raw()); |
+ |
if (FLAG_write_protect_code) { |
uword address = RawObject::ToAddr(instrs.raw()); |
bool status = VirtualMemory::Protect( |
@@ -12754,8 +12835,8 @@ void Code::PrintJSONImpl(JSONStream* stream, bool ref) const { |
jsobj.AddPropertyF("_startAddress", "%" Px "", EntryPoint()); |
jsobj.AddPropertyF("_endAddress", "%" Px "", EntryPoint() + Size()); |
jsobj.AddProperty("_alive", is_alive()); |
- const Array& array = Array::Handle(ObjectPool()); |
- jsobj.AddProperty("_objectPool", array); |
+ const ObjectPool& object_pool = ObjectPool::Handle(GetObjectPool()); |
+ jsobj.AddProperty("_objectPool", object_pool); |
{ |
JSONArray jsarr(&jsobj, "_disassembly"); |
if (is_alive()) { |