OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_OBJECT_H_ | 5 #ifndef VM_OBJECT_H_ |
6 #define VM_OBJECT_H_ | 6 #define VM_OBJECT_H_ |
7 | 7 |
8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
10 #include "platform/utils.h" | 10 #include "platform/utils.h" |
(...skipping 2148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2159 void AttachCode(const Code& value) const; | 2159 void AttachCode(const Code& value) const; |
2160 void SetInstructions(const Code& value) const; | 2160 void SetInstructions(const Code& value) const; |
2161 void ClearCode() const; | 2161 void ClearCode() const; |
2162 | 2162 |
2163 // Disables optimized code and switches to unoptimized code. | 2163 // Disables optimized code and switches to unoptimized code. |
2164 void SwitchToUnoptimizedCode() const; | 2164 void SwitchToUnoptimizedCode() const; |
2165 | 2165 |
2166 // Return the most recently compiled and installed code for this function. | 2166 // Return the most recently compiled and installed code for this function. |
2167 // It is not the only Code object that points to this function. | 2167 // It is not the only Code object that points to this function. |
2168 RawCode* CurrentCode() const { | 2168 RawCode* CurrentCode() const { |
2169 return raw_ptr()->instructions_->ptr()->code_; | 2169 return raw_ptr()->code_; |
2170 } | 2170 } |
2171 | 2171 |
2172 RawCode* unoptimized_code() const { return raw_ptr()->unoptimized_code_; } | 2172 RawCode* unoptimized_code() const { return raw_ptr()->unoptimized_code_; } |
2173 void set_unoptimized_code(const Code& value) const; | 2173 void set_unoptimized_code(const Code& value) const; |
2174 bool HasCode() const; | 2174 bool HasCode() const; |
2175 | 2175 |
| 2176 static intptr_t code_offset() { |
| 2177 return OFFSET_OF(RawFunction, code_); |
| 2178 } |
| 2179 |
2176 static intptr_t entry_point_offset() { | 2180 static intptr_t entry_point_offset() { |
2177 return OFFSET_OF(RawFunction, entry_point_); | 2181 return OFFSET_OF(RawFunction, entry_point_); |
2178 } | 2182 } |
2179 | 2183 |
2180 // Returns true if there is at least one debugger breakpoint | 2184 // Returns true if there is at least one debugger breakpoint |
2181 // set in this function. | 2185 // set in this function. |
2182 bool HasBreakpoint() const; | 2186 bool HasBreakpoint() const; |
2183 | 2187 |
2184 RawContextScope* context_scope() const; | 2188 RawContextScope* context_scope() const; |
2185 void set_context_scope(const ContextScope& value) const; | 2189 void set_context_scope(const ContextScope& value) const; |
(...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3703 FINAL_HEAP_OBJECT_IMPLEMENTATION(ObjectPool, Object); | 3707 FINAL_HEAP_OBJECT_IMPLEMENTATION(ObjectPool, Object); |
3704 friend class Class; | 3708 friend class Class; |
3705 friend class Object; | 3709 friend class Object; |
3706 friend class RawObjectPool; | 3710 friend class RawObjectPool; |
3707 }; | 3711 }; |
3708 | 3712 |
3709 | 3713 |
3710 class Instructions : public Object { | 3714 class Instructions : public Object { |
3711 public: | 3715 public: |
3712 intptr_t size() const { return raw_ptr()->size_; } // Excludes HeaderSize(). | 3716 intptr_t size() const { return raw_ptr()->size_; } // Excludes HeaderSize(). |
3713 RawCode* code() const { return raw_ptr()->code_; } | |
3714 static intptr_t code_offset() { | |
3715 return OFFSET_OF(RawInstructions, code_); | |
3716 } | |
3717 RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; } | |
3718 static intptr_t object_pool_offset() { | |
3719 return OFFSET_OF(RawInstructions, object_pool_); | |
3720 } | |
3721 | 3717 |
3722 uword EntryPoint() const { | 3718 uword EntryPoint() const { |
3723 return reinterpret_cast<uword>(raw_ptr()) + HeaderSize(); | 3719 return reinterpret_cast<uword>(raw_ptr()) + HeaderSize(); |
3724 } | 3720 } |
3725 | 3721 |
3726 static const intptr_t kMaxElements = (kMaxInt32 - | 3722 static const intptr_t kMaxElements = (kMaxInt32 - |
3727 (sizeof(RawInstructions) + | 3723 (sizeof(RawInstructions) + |
3728 sizeof(RawObject) + | 3724 sizeof(RawObject) + |
3729 (2 * OS::kMaxPreferredCodeAlignment))); | 3725 (2 * OS::kMaxPreferredCodeAlignment))); |
3730 | 3726 |
(...skipping 18 matching lines...) Expand all Loading... |
3749 | 3745 |
3750 static RawInstructions* FromEntryPoint(uword entry_point) { | 3746 static RawInstructions* FromEntryPoint(uword entry_point) { |
3751 return reinterpret_cast<RawInstructions*>( | 3747 return reinterpret_cast<RawInstructions*>( |
3752 entry_point - HeaderSize() + kHeapObjectTag); | 3748 entry_point - HeaderSize() + kHeapObjectTag); |
3753 } | 3749 } |
3754 | 3750 |
3755 private: | 3751 private: |
3756 void set_size(intptr_t size) const { | 3752 void set_size(intptr_t size) const { |
3757 StoreNonPointer(&raw_ptr()->size_, size); | 3753 StoreNonPointer(&raw_ptr()->size_, size); |
3758 } | 3754 } |
3759 void set_code(RawCode* code) const { | |
3760 StorePointer(&raw_ptr()->code_, code); | |
3761 } | |
3762 void set_object_pool(RawObjectPool* object_pool) const { | |
3763 StorePointer(&raw_ptr()->object_pool_, object_pool); | |
3764 } | |
3765 | 3755 |
3766 // New is a private method as RawInstruction and RawCode objects should | 3756 // New is a private method as RawInstruction and RawCode objects should |
3767 // only be created using the Code::FinalizeCode method. This method creates | 3757 // only be created using the Code::FinalizeCode method. This method creates |
3768 // the RawInstruction and RawCode objects, sets up the pointer offsets | 3758 // the RawInstruction and RawCode objects, sets up the pointer offsets |
3769 // and links the two in a GC safe manner. | 3759 // and links the two in a GC safe manner. |
3770 static RawInstructions* New(intptr_t size); | 3760 static RawInstructions* New(intptr_t size); |
3771 | 3761 |
3772 FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object); | 3762 FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object); |
3773 friend class Class; | 3763 friend class Class; |
3774 friend class Code; | 3764 friend class Code; |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4086 private: | 4076 private: |
4087 static void UnpackInto(const Array& table, | 4077 static void UnpackInto(const Array& table, |
4088 const TypedData& packed, | 4078 const TypedData& packed, |
4089 GrowableArray<DeoptInstr*>* instructions, | 4079 GrowableArray<DeoptInstr*>* instructions, |
4090 intptr_t length); | 4080 intptr_t length); |
4091 }; | 4081 }; |
4092 | 4082 |
4093 | 4083 |
4094 class Code : public Object { | 4084 class Code : public Object { |
4095 public: | 4085 public: |
| 4086 RawInstructions* active_instructions() const { |
| 4087 return raw_ptr()->active_instructions_; |
| 4088 } |
| 4089 |
4096 RawInstructions* instructions() const { return raw_ptr()->instructions_; } | 4090 RawInstructions* instructions() const { return raw_ptr()->instructions_; } |
4097 | 4091 |
| 4092 static intptr_t saved_instructions_offset() { |
| 4093 return OFFSET_OF(RawCode, instructions_); |
| 4094 } |
| 4095 |
4098 static intptr_t entry_point_offset() { | 4096 static intptr_t entry_point_offset() { |
4099 return OFFSET_OF(RawCode, entry_point_); | 4097 return OFFSET_OF(RawCode, entry_point_); |
4100 } | 4098 } |
4101 | 4099 |
| 4100 RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; } |
| 4101 static intptr_t object_pool_offset() { |
| 4102 return OFFSET_OF(RawCode, object_pool_); |
| 4103 } |
| 4104 |
4102 intptr_t pointer_offsets_length() const { | 4105 intptr_t pointer_offsets_length() const { |
4103 return PtrOffBits::decode(raw_ptr()->state_bits_); | 4106 return PtrOffBits::decode(raw_ptr()->state_bits_); |
4104 } | 4107 } |
4105 | 4108 |
4106 bool is_optimized() const { | 4109 bool is_optimized() const { |
4107 return OptimizedBit::decode(raw_ptr()->state_bits_); | 4110 return OptimizedBit::decode(raw_ptr()->state_bits_); |
4108 } | 4111 } |
4109 void set_is_optimized(bool value) const; | 4112 void set_is_optimized(bool value) const; |
4110 bool is_alive() const { | 4113 bool is_alive() const { |
4111 return AliveBit::decode(raw_ptr()->state_bits_); | 4114 return AliveBit::decode(raw_ptr()->state_bits_); |
4112 } | 4115 } |
4113 void set_is_alive(bool value) const; | 4116 void set_is_alive(bool value) const; |
4114 | 4117 |
4115 uword EntryPoint() const { | 4118 uword EntryPoint() const { |
4116 ASSERT(raw_ptr()->entry_point_ == | 4119 return Instructions::Handle(instructions()).EntryPoint(); |
4117 Instructions::Handle(instructions()).EntryPoint()); | |
4118 return raw_ptr()->entry_point_; | |
4119 } | 4120 } |
4120 intptr_t Size() const { | 4121 intptr_t Size() const { |
4121 const Instructions& instr = Instructions::Handle(instructions()); | 4122 const Instructions& instr = Instructions::Handle(instructions()); |
4122 return instr.size(); | 4123 return instr.size(); |
4123 } | 4124 } |
4124 RawObjectPool* GetObjectPool() const { | 4125 RawObjectPool* GetObjectPool() const { |
4125 const Instructions& instr = Instructions::Handle(instructions()); | 4126 return object_pool(); |
4126 return instr.object_pool(); | |
4127 } | 4127 } |
4128 bool ContainsInstructionAt(uword addr) const { | 4128 bool ContainsInstructionAt(uword addr) const { |
4129 const Instructions& instr = Instructions::Handle(instructions()); | 4129 const Instructions& instr = Instructions::Handle(instructions()); |
4130 const uword offset = addr - instr.EntryPoint(); | 4130 const uword offset = addr - instr.EntryPoint(); |
4131 return offset < static_cast<uword>(instr.size()); | 4131 return offset < static_cast<uword>(instr.size()); |
4132 } | 4132 } |
4133 | 4133 |
4134 // Returns true if there is a debugger breakpoint set in this code object. | 4134 // Returns true if there is a debugger breakpoint set in this code object. |
4135 bool HasBreakpoint() const; | 4135 bool HasBreakpoint() const; |
4136 | 4136 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4311 int32_t GetPointerOffsetAt(int index) const { | 4311 int32_t GetPointerOffsetAt(int index) const { |
4312 NoSafepointScope no_safepoint; | 4312 NoSafepointScope no_safepoint; |
4313 return *PointerOffsetAddrAt(index); | 4313 return *PointerOffsetAddrAt(index); |
4314 } | 4314 } |
4315 intptr_t GetTokenIndexOfPC(uword pc) const; | 4315 intptr_t GetTokenIndexOfPC(uword pc) const; |
4316 | 4316 |
4317 enum { | 4317 enum { |
4318 kInvalidPc = -1 | 4318 kInvalidPc = -1 |
4319 }; | 4319 }; |
4320 | 4320 |
4321 // Returns 0 if code is not patchable | |
4322 uword GetEntryPatchPc() const; | |
4323 uword GetPatchCodePc() const; | |
4324 | |
4325 uword GetLazyDeoptPc() const; | 4321 uword GetLazyDeoptPc() const; |
4326 | 4322 |
4327 // Find pc, return 0 if not found. | 4323 // Find pc, return 0 if not found. |
4328 uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const; | 4324 uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const; |
4329 intptr_t GetDeoptIdForOsr(uword pc) const; | 4325 intptr_t GetDeoptIdForOsr(uword pc) const; |
4330 | 4326 |
4331 RawString* Name() const; | 4327 RawString* Name() const; |
4332 RawString* PrettyName() const; | 4328 RawString* PrettyName() const; |
4333 | 4329 |
4334 int64_t compile_timestamp() const { | 4330 int64_t compile_timestamp() const { |
4335 return raw_ptr()->compile_timestamp_; | 4331 return raw_ptr()->compile_timestamp_; |
4336 } | 4332 } |
4337 | 4333 |
4338 intptr_t entry_patch_pc_offset() const { | |
4339 return raw_ptr()->entry_patch_pc_offset_; | |
4340 } | |
4341 void set_entry_patch_pc_offset(intptr_t pc) const { | |
4342 StoreNonPointer(&raw_ptr()->entry_patch_pc_offset_, pc); | |
4343 } | |
4344 | |
4345 | |
4346 intptr_t patch_code_pc_offset() const { | |
4347 return raw_ptr()->patch_code_pc_offset_; | |
4348 } | |
4349 void set_patch_code_pc_offset(intptr_t pc) const { | |
4350 StoreNonPointer(&raw_ptr()->patch_code_pc_offset_, pc); | |
4351 } | |
4352 | |
4353 | |
4354 intptr_t lazy_deopt_pc_offset() const { | 4334 intptr_t lazy_deopt_pc_offset() const { |
4355 return raw_ptr()->lazy_deopt_pc_offset_; | 4335 return raw_ptr()->lazy_deopt_pc_offset_; |
4356 } | 4336 } |
4357 void set_lazy_deopt_pc_offset(intptr_t pc) const { | 4337 void set_lazy_deopt_pc_offset(intptr_t pc) const { |
4358 StoreNonPointer(&raw_ptr()->lazy_deopt_pc_offset_, pc); | 4338 StoreNonPointer(&raw_ptr()->lazy_deopt_pc_offset_, pc); |
4359 } | 4339 } |
4360 | 4340 |
4361 bool IsAllocationStubCode() const; | 4341 bool IsAllocationStubCode() const; |
4362 bool IsStubCode() const; | 4342 bool IsStubCode() const; |
4363 bool IsFunctionCode() const; | 4343 bool IsFunctionCode() const; |
4364 | 4344 |
4365 private: | 4345 private: |
4366 void set_state_bits(intptr_t bits) const; | 4346 void set_state_bits(intptr_t bits) const; |
4367 | 4347 |
| 4348 void set_object_pool(RawObjectPool* object_pool) const { |
| 4349 StorePointer(&raw_ptr()->object_pool_, object_pool); |
| 4350 } |
| 4351 |
4368 friend class RawObject; // For RawObject::SizeFromClass(). | 4352 friend class RawObject; // For RawObject::SizeFromClass(). |
4369 friend class RawCode; | 4353 friend class RawCode; |
4370 enum { | 4354 enum { |
4371 kOptimizedBit = 0, | 4355 kOptimizedBit = 0, |
4372 kAliveBit = 1, | 4356 kAliveBit = 1, |
4373 kPtrOffBit = 2, | 4357 kPtrOffBit = 2, |
4374 kPtrOffSize = 30, | 4358 kPtrOffSize = 30, |
4375 }; | 4359 }; |
4376 | 4360 |
4377 class OptimizedBit : public BitField<bool, kOptimizedBit, 1> {}; | 4361 class OptimizedBit : public BitField<bool, kOptimizedBit, 1> {}; |
4378 class AliveBit : public BitField<bool, kAliveBit, 1> {}; | 4362 class AliveBit : public BitField<bool, kAliveBit, 1> {}; |
4379 class PtrOffBits : public BitField<intptr_t, kPtrOffBit, kPtrOffSize> {}; | 4363 class PtrOffBits : public BitField<intptr_t, kPtrOffBit, kPtrOffSize> {}; |
4380 | 4364 |
4381 // An object finder visitor interface. | 4365 // An object finder visitor interface. |
4382 class FindRawCodeVisitor : public FindObjectVisitor { | 4366 class FindRawCodeVisitor : public FindObjectVisitor { |
4383 public: | 4367 public: |
4384 explicit FindRawCodeVisitor(uword pc) | 4368 explicit FindRawCodeVisitor(uword pc) |
4385 : FindObjectVisitor(Isolate::Current()), pc_(pc) { } | 4369 : FindObjectVisitor(Isolate::Current()), pc_(pc) { } |
4386 virtual ~FindRawCodeVisitor() { } | 4370 virtual ~FindRawCodeVisitor() { } |
4387 | 4371 |
4388 virtual uword filter_addr() const { return pc_; } | |
4389 | |
4390 // Check if object matches find condition. | 4372 // Check if object matches find condition. |
4391 virtual bool FindObject(RawObject* obj) const; | 4373 virtual bool FindObject(RawObject* obj) const; |
4392 | 4374 |
4393 private: | 4375 private: |
4394 const uword pc_; | 4376 const uword pc_; |
4395 | 4377 |
4396 DISALLOW_COPY_AND_ASSIGN(FindRawCodeVisitor); | 4378 DISALLOW_COPY_AND_ASSIGN(FindRawCodeVisitor); |
4397 }; | 4379 }; |
4398 | 4380 |
4399 static bool IsOptimized(RawCode* code) { | 4381 static bool IsOptimized(RawCode* code) { |
4400 return Code::OptimizedBit::decode(code->ptr()->state_bits_); | 4382 return Code::OptimizedBit::decode(code->ptr()->state_bits_); |
4401 } | 4383 } |
4402 | 4384 |
4403 static const intptr_t kEntrySize = sizeof(int32_t); // NOLINT | 4385 static const intptr_t kEntrySize = sizeof(int32_t); // NOLINT |
4404 | 4386 |
4405 void set_compile_timestamp(int64_t timestamp) const { | 4387 void set_compile_timestamp(int64_t timestamp) const { |
4406 StoreNonPointer(&raw_ptr()->compile_timestamp_, timestamp); | 4388 StoreNonPointer(&raw_ptr()->compile_timestamp_, timestamp); |
4407 } | 4389 } |
4408 | 4390 |
4409 void set_instructions(RawInstructions* instructions) { | 4391 void set_active_instructions(RawInstructions* instructions) const { |
4410 // RawInstructions are never allocated in New space and hence a | 4392 // RawInstructions are never allocated in New space and hence a |
4411 // store buffer update is not needed here. | 4393 // store buffer update is not needed here. |
| 4394 StorePointer(&raw_ptr()->active_instructions_, instructions); |
| 4395 StoreNonPointer(&raw_ptr()->entry_point_, |
| 4396 reinterpret_cast<uword>(instructions->ptr()) + |
| 4397 Instructions::HeaderSize()); |
| 4398 } |
| 4399 |
| 4400 void set_instructions(RawInstructions* instructions) const { |
4412 StorePointer(&raw_ptr()->instructions_, instructions); | 4401 StorePointer(&raw_ptr()->instructions_, instructions); |
4413 uword entry_point = reinterpret_cast<uword>(instructions->ptr()) + | |
4414 Instructions::HeaderSize(); | |
4415 StoreNonPointer(&raw_ptr()->entry_point_, entry_point); | |
4416 } | 4402 } |
4417 | 4403 |
4418 void set_pointer_offsets_length(intptr_t value) { | 4404 void set_pointer_offsets_length(intptr_t value) { |
4419 // The number of fixups is limited to 1-billion. | 4405 // The number of fixups is limited to 1-billion. |
4420 ASSERT(Utils::IsUint(30, value)); | 4406 ASSERT(Utils::IsUint(30, value)); |
4421 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); | 4407 set_state_bits(PtrOffBits::update(value, raw_ptr()->state_bits_)); |
4422 } | 4408 } |
4423 int32_t* PointerOffsetAddrAt(int index) const { | 4409 int32_t* PointerOffsetAddrAt(int index) const { |
4424 ASSERT(index >= 0); | 4410 ASSERT(index >= 0); |
4425 ASSERT(index < pointer_offsets_length()); | 4411 ASSERT(index < pointer_offsets_length()); |
(...skipping 13 matching lines...) Expand all Loading... |
4439 | 4425 |
4440 // New is a private method as RawInstruction and RawCode objects should | 4426 // New is a private method as RawInstruction and RawCode objects should |
4441 // only be created using the Code::FinalizeCode method. This method creates | 4427 // only be created using the Code::FinalizeCode method. This method creates |
4442 // the RawInstruction and RawCode objects, sets up the pointer offsets | 4428 // the RawInstruction and RawCode objects, sets up the pointer offsets |
4443 // and links the two in a GC safe manner. | 4429 // and links the two in a GC safe manner. |
4444 static RawCode* New(intptr_t pointer_offsets_length); | 4430 static RawCode* New(intptr_t pointer_offsets_length); |
4445 | 4431 |
4446 FINAL_HEAP_OBJECT_IMPLEMENTATION(Code, Object); | 4432 FINAL_HEAP_OBJECT_IMPLEMENTATION(Code, Object); |
4447 friend class Class; | 4433 friend class Class; |
4448 friend class SnapshotWriter; | 4434 friend class SnapshotWriter; |
4449 | 4435 friend class CodePatcher; // for set_instructions |
4450 // So that the RawFunction pointer visitor can determine whether code the | 4436 // So that the RawFunction pointer visitor can determine whether code the |
4451 // function points to is optimized. | 4437 // function points to is optimized. |
4452 friend class RawFunction; | 4438 friend class RawFunction; |
4453 }; | 4439 }; |
4454 | 4440 |
4455 | 4441 |
4456 class Context : public Object { | 4442 class Context : public Object { |
4457 public: | 4443 public: |
4458 RawContext* parent() const { return raw_ptr()->parent_; } | 4444 RawContext* parent() const { return raw_ptr()->parent_; } |
4459 void set_parent(const Context& parent) const { | 4445 void set_parent(const Context& parent) const { |
(...skipping 3669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8129 | 8115 |
8130 | 8116 |
8131 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 8117 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
8132 intptr_t index) { | 8118 intptr_t index) { |
8133 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 8119 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
8134 } | 8120 } |
8135 | 8121 |
8136 } // namespace dart | 8122 } // namespace dart |
8137 | 8123 |
8138 #endif // VM_OBJECT_H_ | 8124 #endif // VM_OBJECT_H_ |
OLD | NEW |