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