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 #include "vm/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 DECLARE_FLAG(bool, trace_deoptimization); | 76 DECLARE_FLAG(bool, trace_deoptimization); |
77 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 77 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
78 DECLARE_FLAG(bool, write_protect_code); | 78 DECLARE_FLAG(bool, write_protect_code); |
79 | 79 |
80 | 80 |
81 static const char* kGetterPrefix = "get:"; | 81 static const char* kGetterPrefix = "get:"; |
82 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); | 82 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); |
83 static const char* kSetterPrefix = "set:"; | 83 static const char* kSetterPrefix = "set:"; |
84 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); | 84 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); |
85 | 85 |
| 86 // A cache of VM heap allocated preinitialized empty ic data entry arrays. |
| 87 RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount]; |
| 88 |
86 cpp_vtable Object::handle_vtable_ = 0; | 89 cpp_vtable Object::handle_vtable_ = 0; |
87 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 }; | 90 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 }; |
88 cpp_vtable Smi::handle_vtable_ = 0; | 91 cpp_vtable Smi::handle_vtable_ = 0; |
89 | 92 |
90 // These are initialized to a value that will force a illegal memory access if | 93 // These are initialized to a value that will force a illegal memory access if |
91 // they are being used. | 94 // they are being used. |
92 #if defined(RAW_NULL) | 95 #if defined(RAW_NULL) |
93 #error RAW_NULL should not be defined. | 96 #error RAW_NULL should not be defined. |
94 #endif | 97 #endif |
95 #define RAW_NULL kHeapObjectTag | 98 #define RAW_NULL kHeapObjectTag |
(...skipping 12513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12609 if (cid == kObjectCid) { | 12612 if (cid == kObjectCid) { |
12610 return true; | 12613 return true; |
12611 } | 12614 } |
12612 } | 12615 } |
12613 return false; | 12616 return false; |
12614 } | 12617 } |
12615 return true; | 12618 return true; |
12616 } | 12619 } |
12617 | 12620 |
12618 | 12621 |
12619 RawICData* ICData::New() { | 12622 void ICData::InitOnce() { |
12620 ICData& result = ICData::Handle(); | 12623 for (int i = 0; i < kCachedICDataArrayCount; i++) { |
12621 { | 12624 cached_icdata_arrays_[i] = ICData::NewNonCachedEmptyICDataArray(i); |
12622 // IC data objects are long living objects, allocate them in old generation. | |
12623 RawObject* raw = Object::Allocate(ICData::kClassId, | |
12624 ICData::InstanceSize(), | |
12625 Heap::kOld); | |
12626 NoSafepointScope no_safepoint; | |
12627 result ^= raw; | |
12628 } | 12625 } |
12629 result.set_deopt_id(Thread::kNoDeoptId); | |
12630 result.set_state_bits(0); | |
12631 return result.raw(); | |
12632 } | 12626 } |
12633 | 12627 |
12634 | 12628 |
12635 RawICData* ICData::New(const Function& owner, | 12629 RawArray* ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested) { |
12636 const String& target_name, | 12630 // IC data array must be null terminated (sentinel entry). |
12637 const Array& arguments_descriptor, | 12631 const intptr_t len = TestEntryLengthFor(num_args_tested); |
12638 intptr_t deopt_id, | 12632 const Array& array = Array::Handle(Array::New(len, Heap::kOld)); |
12639 intptr_t num_args_tested) { | 12633 WriteSentinel(array, len); |
| 12634 array.MakeImmutable(); |
| 12635 return array.raw(); |
| 12636 } |
| 12637 |
| 12638 |
| 12639 RawArray* ICData::NewEmptyICDataArray(intptr_t num_args_tested) { |
| 12640 ASSERT(num_args_tested >= 0); |
| 12641 if (num_args_tested < kCachedICDataArrayCount) { |
| 12642 return cached_icdata_arrays_[num_args_tested]; |
| 12643 } |
| 12644 return NewNonCachedEmptyICDataArray(num_args_tested); |
| 12645 } |
| 12646 |
| 12647 |
| 12648 |
| 12649 // Does not initialize ICData array. |
| 12650 RawICData* ICData::NewDescriptor(Zone* zone, |
| 12651 const Function& owner, |
| 12652 const String& target_name, |
| 12653 const Array& arguments_descriptor, |
| 12654 intptr_t deopt_id, |
| 12655 intptr_t num_args_tested) { |
12640 ASSERT(!owner.IsNull()); | 12656 ASSERT(!owner.IsNull()); |
12641 ASSERT(!target_name.IsNull()); | 12657 ASSERT(!target_name.IsNull()); |
12642 ASSERT(!arguments_descriptor.IsNull()); | 12658 ASSERT(!arguments_descriptor.IsNull()); |
12643 ASSERT(Object::icdata_class() != Class::null()); | 12659 ASSERT(Object::icdata_class() != Class::null()); |
12644 ASSERT(num_args_tested >= 0); | 12660 ASSERT(num_args_tested >= 0); |
12645 ICData& result = ICData::Handle(); | 12661 ICData& result = ICData::Handle(zone); |
12646 { | 12662 { |
12647 // IC data objects are long living objects, allocate them in old generation. | 12663 // IC data objects are long living objects, allocate them in old generation. |
12648 RawObject* raw = Object::Allocate(ICData::kClassId, | 12664 RawObject* raw = Object::Allocate(ICData::kClassId, |
12649 ICData::InstanceSize(), | 12665 ICData::InstanceSize(), |
12650 Heap::kOld); | 12666 Heap::kOld); |
12651 NoSafepointScope no_safepoint; | 12667 NoSafepointScope no_safepoint; |
12652 result ^= raw; | 12668 result ^= raw; |
12653 } | 12669 } |
12654 result.set_owner(owner); | 12670 result.set_owner(owner); |
12655 result.set_target_name(target_name); | 12671 result.set_target_name(target_name); |
12656 result.set_arguments_descriptor(arguments_descriptor); | 12672 result.set_arguments_descriptor(arguments_descriptor); |
12657 result.set_deopt_id(deopt_id); | 12673 result.set_deopt_id(deopt_id); |
12658 result.set_state_bits(0); | 12674 result.set_state_bits(0); |
12659 result.SetNumArgsTested(num_args_tested); | 12675 result.SetNumArgsTested(num_args_tested); |
12660 // Number of array elements in one test entry. | |
12661 intptr_t len = result.TestEntryLength(); | |
12662 // IC data array must be null terminated (sentinel entry). | |
12663 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); | |
12664 WriteSentinel(ic_data, result.TestEntryLength()); | |
12665 result.set_ic_data_array(ic_data); | |
12666 return result.raw(); | 12676 return result.raw(); |
12667 } | 12677 } |
12668 | 12678 |
| 12679 |
| 12680 RawICData* ICData::New() { |
| 12681 ICData& result = ICData::Handle(); |
| 12682 { |
| 12683 // IC data objects are long living objects, allocate them in old generation. |
| 12684 RawObject* raw = Object::Allocate(ICData::kClassId, |
| 12685 ICData::InstanceSize(), |
| 12686 Heap::kOld); |
| 12687 NoSafepointScope no_safepoint; |
| 12688 result ^= raw; |
| 12689 } |
| 12690 result.set_deopt_id(Thread::kNoDeoptId); |
| 12691 result.set_state_bits(0); |
| 12692 return result.raw(); |
| 12693 } |
| 12694 |
| 12695 |
| 12696 RawICData* ICData::New(const Function& owner, |
| 12697 const String& target_name, |
| 12698 const Array& arguments_descriptor, |
| 12699 intptr_t deopt_id, |
| 12700 intptr_t num_args_tested) { |
| 12701 Zone* zone = Thread::Current()->zone(); |
| 12702 const ICData& result = ICData::Handle(zone, |
| 12703 NewDescriptor(zone, |
| 12704 owner, |
| 12705 target_name, |
| 12706 arguments_descriptor, |
| 12707 deopt_id, |
| 12708 num_args_tested)); |
| 12709 result.set_ic_data_array( |
| 12710 Array::Handle(zone, NewEmptyICDataArray(num_args_tested))); |
| 12711 return result.raw(); |
| 12712 } |
| 12713 |
12669 | 12714 |
12670 RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) { | 12715 RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) { |
12671 const ICData& result = ICData::Handle(ICData::New( | 12716 const ICData& result = ICData::Handle(ICData::New( |
12672 Function::Handle(from.owner()), | 12717 Function::Handle(from.owner()), |
12673 String::Handle(from.target_name()), | 12718 String::Handle(from.target_name()), |
12674 Array::Handle(from.arguments_descriptor()), | 12719 Array::Handle(from.arguments_descriptor()), |
12675 from.deopt_id(), | 12720 from.deopt_id(), |
12676 num_args_tested)); | 12721 num_args_tested)); |
12677 // Copy deoptimization reasons. | 12722 // Copy deoptimization reasons. |
12678 result.SetDeoptReasons(from.DeoptReasons()); | 12723 result.SetDeoptReasons(from.DeoptReasons()); |
(...skipping 9103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21782 return tag_label.ToCString(); | 21827 return tag_label.ToCString(); |
21783 } | 21828 } |
21784 | 21829 |
21785 | 21830 |
21786 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 21831 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
21787 Instance::PrintJSONImpl(stream, ref); | 21832 Instance::PrintJSONImpl(stream, ref); |
21788 } | 21833 } |
21789 | 21834 |
21790 | 21835 |
21791 } // namespace dart | 21836 } // namespace dart |
OLD | NEW |