Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index aeb798833557a3b06b90ade0ce623bd83e8a7ac1..5386ffb9a11f03368143ae8196ad8c487e2c5de6 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -95,6 +95,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::script_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
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::object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
RawClass* Object::instructions_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); |
@@ -403,6 +405,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(); |
@@ -541,6 +544,9 @@ void Object::InitOnce(Isolate* isolate) { |
cls = Class::New<Code>(); |
code_class_ = cls.raw(); |
+ cls = Class::New<ObjectPool>(); |
+ object_pool_class_ = cls.raw(); |
+ |
cls = Class::New<Instructions>(); |
instructions_class_ = cls.raw(); |
@@ -625,6 +631,22 @@ 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); |
+ empty_object_pool_->StoreNonPointer( |
+ &empty_object_pool_->raw_ptr()->num_tagged_entries_, 0); |
+ } |
+ |
// Allocate and initialize the empty_descriptors instance. |
{ |
uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld); |
@@ -810,6 +832,7 @@ void Object::FinalizeVMIsolate(Isolate* isolate) { |
SET_CLASS_NAME(library, LibraryClass); |
SET_CLASS_NAME(namespace, Namespace); |
SET_CLASS_NAME(code, Code); |
+ SET_CLASS_NAME(object_pool, ObjectPool); |
SET_CLASS_NAME(instructions, Instructions); |
SET_CLASS_NAME(pc_descriptors, PcDescriptors); |
SET_CLASS_NAME(stackmap, Stackmap); |
@@ -3213,6 +3236,8 @@ RawString* Class::GenerateUserVisibleName() const { |
return Symbols::Namespace().raw(); |
case kCodeCid: |
return Symbols::Code().raw(); |
+ case kObjectPoolCid: |
+ return Symbols::ObjectPool().raw(); |
case kInstructionsCid: |
return Symbols::Instructions().raw(); |
case kPcDescriptorsCid: |
@@ -10512,6 +10537,53 @@ Class& cls = Class::Handle(); |
#endif // defined(DART_NO_SNAPSHOT). |
+RawObjectPool* ObjectPool::New(intptr_t len, intptr_t num_tagged_entries) { |
+ ASSERT(Object::object_pool_class() != Class::null()); |
+ ASSERT(num_tagged_entries <= len); |
+ 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); |
+ result.SetNumTaggedEntries(num_tagged_entries); |
+ } |
+ return result.raw(); |
+} |
+ |
+ |
+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 (i < NumTaggedEntries()) { |
+ ISL_Print(" %" Pd ": 0x%" Px " %s\n", i, |
+ reinterpret_cast<uword>(ObjectAt(i)), |
+ Object::Handle(ObjectAt(i)).ToCString()); |
+ } else { |
+ ISL_Print(" %" Pd ": 0x%" Px "\n", i, RawValueAt(i)); |
+ } |
+ } |
+ ISL_Print("}\n"); |
+} |
+ |
+ |
RawInstructions* Instructions::New(intptr_t size) { |
ASSERT(Object::instructions_class() != Class::null()); |
if (size < 0 || size > kMaxElements) { |
@@ -12313,6 +12385,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 |
@@ -12363,17 +12437,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( |
@@ -12600,8 +12667,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()) { |