Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1203)

Side by Side Diff: runtime/vm/object.cc

Issue 1965823002: Initial isolate reload support (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "vm/bit_vector.h" 11 #include "vm/bit_vector.h"
12 #include "vm/bootstrap.h" 12 #include "vm/bootstrap.h"
13 #include "vm/class_finalizer.h" 13 #include "vm/class_finalizer.h"
14 #include "vm/code_observers.h" 14 #include "vm/code_observers.h"
15 #include "vm/compiler.h" 15 #include "vm/compiler.h"
16 #include "vm/compiler_stats.h" 16 #include "vm/compiler_stats.h"
17 #include "vm/dart.h" 17 #include "vm/dart.h"
18 #include "vm/dart_api_state.h" 18 #include "vm/dart_api_state.h"
19 #include "vm/dart_entry.h" 19 #include "vm/dart_entry.h"
20 #include "vm/datastream.h" 20 #include "vm/datastream.h"
21 #include "vm/debugger.h" 21 #include "vm/debugger.h"
22 #include "vm/deopt_instructions.h" 22 #include "vm/deopt_instructions.h"
23 #include "vm/disassembler.h" 23 #include "vm/disassembler.h"
24 #include "vm/double_conversion.h" 24 #include "vm/double_conversion.h"
25 #include "vm/exceptions.h" 25 #include "vm/exceptions.h"
26 #include "vm/growable_array.h" 26 #include "vm/growable_array.h"
27 #include "vm/hash_table.h" 27 #include "vm/hash_table.h"
28 #include "vm/heap.h" 28 #include "vm/heap.h"
29 #include "vm/intrinsifier.h" 29 #include "vm/intrinsifier.h"
30 #include "vm/isolate_reload.h"
30 #include "vm/object_store.h" 31 #include "vm/object_store.h"
31 #include "vm/parser.h" 32 #include "vm/parser.h"
32 #include "vm/precompiler.h" 33 #include "vm/precompiler.h"
33 #include "vm/profiler.h" 34 #include "vm/profiler.h"
35 #include "vm/resolver.h"
34 #include "vm/reusable_handles.h" 36 #include "vm/reusable_handles.h"
35 #include "vm/runtime_entry.h" 37 #include "vm/runtime_entry.h"
36 #include "vm/scopes.h" 38 #include "vm/scopes.h"
37 #include "vm/stack_frame.h" 39 #include "vm/stack_frame.h"
38 #include "vm/symbols.h" 40 #include "vm/symbols.h"
39 #include "vm/tags.h" 41 #include "vm/tags.h"
40 #include "vm/thread_registry.h" 42 #include "vm/thread_registry.h"
41 #include "vm/timeline.h" 43 #include "vm/timeline.h"
42 #include "vm/timer.h" 44 #include "vm/timer.h"
43 #include "vm/unicode.h" 45 #include "vm/unicode.h"
(...skipping 10 matching lines...) Expand all
54 "When possible, partially or fully overlap the type arguments of a type " 56 "When possible, partially or fully overlap the type arguments of a type "
55 "with the type arguments of its super type."); 57 "with the type arguments of its super type.");
56 DEFINE_FLAG(bool, show_internal_names, false, 58 DEFINE_FLAG(bool, show_internal_names, false,
57 "Show names of internal classes (e.g. \"OneByteString\") in error messages " 59 "Show names of internal classes (e.g. \"OneByteString\") in error messages "
58 "instead of showing the corresponding interface names (e.g. \"String\")"); 60 "instead of showing the corresponding interface names (e.g. \"String\")");
59 DEFINE_FLAG(bool, use_lib_cache, true, "Use library name cache"); 61 DEFINE_FLAG(bool, use_lib_cache, true, "Use library name cache");
60 DEFINE_FLAG(bool, use_exp_cache, true, "Use library exported name cache"); 62 DEFINE_FLAG(bool, use_exp_cache, true, "Use library exported name cache");
61 DEFINE_FLAG(bool, ignore_patch_signature_mismatch, false, 63 DEFINE_FLAG(bool, ignore_patch_signature_mismatch, false,
62 "Ignore patch file member signature mismatch."); 64 "Ignore patch file member signature mismatch.");
63 65
66 DEFINE_FLAG(bool, remove_script_timestamps_for_test, false,
67 "Remove script timestamps to allow for deterministic testing.");
68
64 DECLARE_FLAG(bool, show_invisible_frames); 69 DECLARE_FLAG(bool, show_invisible_frames);
65 DECLARE_FLAG(bool, trace_deoptimization); 70 DECLARE_FLAG(bool, trace_deoptimization);
66 DECLARE_FLAG(bool, trace_deoptimization_verbose); 71 DECLARE_FLAG(bool, trace_deoptimization_verbose);
72 DECLARE_FLAG(bool, trace_reload);
67 DECLARE_FLAG(bool, write_protect_code); 73 DECLARE_FLAG(bool, write_protect_code);
68 DECLARE_FLAG(bool, support_externalizable_strings); 74 DECLARE_FLAG(bool, support_externalizable_strings);
69 75
70 76
71 static const char* const kGetterPrefix = "get:"; 77 static const char* const kGetterPrefix = "get:";
72 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); 78 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix);
73 static const char* const kSetterPrefix = "set:"; 79 static const char* const kSetterPrefix = "set:";
74 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); 80 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix);
75 81
76 // A cache of VM heap allocated preinitialized empty ic data entry arrays. 82 // A cache of VM heap allocated preinitialized empty ic data entry arrays.
(...skipping 2689 matching lines...) Expand 10 before | Expand all | Expand 10 after
2766 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); 2772 DEBUG_ASSERT(IsMutatorOrAtSafepoint());
2767 ASSERT(code.is_optimized()); 2773 ASSERT(code.is_optimized());
2768 CHACodeArray a(*this); 2774 CHACodeArray a(*this);
2769 a.Register(code); 2775 a.Register(code);
2770 } 2776 }
2771 2777
2772 2778
2773 void Class::DisableCHAOptimizedCode(const Class& subclass) { 2779 void Class::DisableCHAOptimizedCode(const Class& subclass) {
2774 ASSERT(Thread::Current()->IsMutatorThread()); 2780 ASSERT(Thread::Current()->IsMutatorThread());
2775 CHACodeArray a(*this); 2781 CHACodeArray a(*this);
2776 if (FLAG_trace_deoptimization && a.HasCodes()) { 2782 if (FLAG_trace_deoptimization && a.HasCodes() && !subclass.IsNull()) {
2777 THR_Print("Adding subclass %s\n", subclass.ToCString()); 2783 THR_Print("Adding subclass %s\n", subclass.ToCString());
2778 } 2784 }
2779 a.DisableCode(); 2785 a.DisableCode();
2780 } 2786 }
2781 2787
2782 2788
2789 void Class::DisableAllCHAOptimizedCode() {
2790 DisableCHAOptimizedCode(Class::Handle());
2791 }
2792
2793
2783 bool Class::TraceAllocation(Isolate* isolate) const { 2794 bool Class::TraceAllocation(Isolate* isolate) const {
2784 ClassTable* class_table = isolate->class_table(); 2795 ClassTable* class_table = isolate->class_table();
2785 return class_table->TraceAllocationFor(id()); 2796 return class_table->TraceAllocationFor(id());
2786 } 2797 }
2787 2798
2788 2799
2789 void Class::SetTraceAllocation(bool trace_allocation) const { 2800 void Class::SetTraceAllocation(bool trace_allocation) const {
2790 Isolate* isolate = Isolate::Current(); 2801 Isolate* isolate = Isolate::Current();
2791 const bool changed = trace_allocation != this->TraceAllocation(isolate); 2802 const bool changed = trace_allocation != this->TraceAllocation(isolate);
2792 if (changed) { 2803 if (changed) {
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
3117 const Array& new_arr = Array::Handle( 3128 const Array& new_arr = Array::Handle(
3118 Array::Grow(arr, num_old_fields + num_new_fields, Heap::kOld)); 3129 Array::Grow(arr, num_old_fields + num_new_fields, Heap::kOld));
3119 for (intptr_t i = 0; i < num_new_fields; i++) { 3130 for (intptr_t i = 0; i < num_new_fields; i++) {
3120 new_arr.SetAt(i + num_old_fields, *new_fields.At(i)); 3131 new_arr.SetAt(i + num_old_fields, *new_fields.At(i));
3121 } 3132 }
3122 SetFields(new_arr); 3133 SetFields(new_arr);
3123 } 3134 }
3124 3135
3125 3136
3126 template <class FakeInstance> 3137 template <class FakeInstance>
3127 RawClass* Class::New(intptr_t index) { 3138 RawClass* Class::NewCommon(intptr_t index) {
3128 ASSERT(Object::class_class() != Class::null()); 3139 ASSERT(Object::class_class() != Class::null());
3129 Class& result = Class::Handle(); 3140 Class& result = Class::Handle();
3130 { 3141 {
3131 RawObject* raw = Object::Allocate(Class::kClassId, 3142 RawObject* raw = Object::Allocate(Class::kClassId,
3132 Class::InstanceSize(), 3143 Class::InstanceSize(),
3133 Heap::kOld); 3144 Heap::kOld);
3134 NoSafepointScope no_safepoint; 3145 NoSafepointScope no_safepoint;
3135 result ^= raw; 3146 result ^= raw;
3136 } 3147 }
3137 FakeInstance fake; 3148 FakeInstance fake;
3138 ASSERT(fake.IsInstance()); 3149 ASSERT(fake.IsInstance());
3139 result.set_handle_vtable(fake.vtable()); 3150 result.set_handle_vtable(fake.vtable());
3140 result.set_instance_size(FakeInstance::InstanceSize()); 3151 result.set_instance_size(FakeInstance::InstanceSize());
3141 result.set_next_field_offset(FakeInstance::NextFieldOffset()); 3152 result.set_next_field_offset(FakeInstance::NextFieldOffset());
3142 result.set_id(index); 3153 result.set_id(index);
3143 result.set_state_bits(0); 3154 result.set_state_bits(0);
3144 result.set_type_arguments_field_offset_in_words(kNoTypeArguments); 3155 result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
3145 result.set_num_type_arguments(kUnknownNumTypeArguments); 3156 result.set_num_type_arguments(kUnknownNumTypeArguments);
3146 result.set_num_own_type_arguments(kUnknownNumTypeArguments); 3157 result.set_num_own_type_arguments(kUnknownNumTypeArguments);
3147 result.set_num_native_fields(0); 3158 result.set_num_native_fields(0);
3148 result.set_token_pos(TokenPosition::kNoSource); 3159 result.set_token_pos(TokenPosition::kNoSource);
3149 result.InitEmptyFields(); 3160 result.InitEmptyFields();
3161 return result.raw();
3162 }
3163
3164
3165 template <class FakeInstance>
3166 RawClass* Class::New(intptr_t index) {
3167 Class& result = Class::Handle(NewCommon<FakeInstance>(index));
3150 Isolate::Current()->RegisterClass(result); 3168 Isolate::Current()->RegisterClass(result);
3151 return result.raw(); 3169 return result.raw();
3152 } 3170 }
3153 3171
3154 3172
3155 RawClass* Class::New(const String& name, 3173 RawClass* Class::New(const Library& lib,
3174 const String& name,
3156 const Script& script, 3175 const Script& script,
3157 TokenPosition token_pos) { 3176 TokenPosition token_pos) {
3158 Class& result = Class::Handle(New<Instance>(kIllegalCid)); 3177 Class& result = Class::Handle(NewCommon<Instance>(kIllegalCid));
3178 result.set_library(lib);
3159 result.set_name(name); 3179 result.set_name(name);
3160 result.set_script(script); 3180 result.set_script(script);
3161 result.set_token_pos(token_pos); 3181 result.set_token_pos(token_pos);
3182 Isolate::Current()->RegisterClass(result);
3162 return result.raw(); 3183 return result.raw();
3163 } 3184 }
3164 3185
3165 3186
3166 RawClass* Class::NewNativeWrapper(const Library& library, 3187 RawClass* Class::NewNativeWrapper(const Library& library,
3167 const String& name, 3188 const String& name,
3168 int field_count) { 3189 int field_count) {
3169 Class& cls = Class::Handle(library.LookupClass(name)); 3190 Class& cls = Class::Handle(library.LookupClass(name));
3170 if (cls.IsNull()) { 3191 if (cls.IsNull()) {
3171 cls = New(name, Script::Handle(), TokenPosition::kNoSource); 3192 cls = New(library, name, Script::Handle(), TokenPosition::kNoSource);
3172 cls.SetFields(Object::empty_array()); 3193 cls.SetFields(Object::empty_array());
3173 cls.SetFunctions(Object::empty_array()); 3194 cls.SetFunctions(Object::empty_array());
3174 // Set super class to Object. 3195 // Set super class to Object.
3175 cls.set_super_type(Type::Handle(Type::ObjectType())); 3196 cls.set_super_type(Type::Handle(Type::ObjectType()));
3176 // Compute instance size. First word contains a pointer to a properly 3197 // Compute instance size. First word contains a pointer to a properly
3177 // sized typed array once the first native field has been set. 3198 // sized typed array once the first native field has been set.
3178 intptr_t instance_size = sizeof(RawInstance) + kWordSize; 3199 intptr_t instance_size = sizeof(RawInstance) + kWordSize;
3179 cls.set_instance_size(RoundedAllocationSize(instance_size)); 3200 cls.set_instance_size(RoundedAllocationSize(instance_size));
3180 cls.set_next_field_offset(instance_size); 3201 cls.set_next_field_offset(instance_size);
3181 cls.set_num_native_fields(field_count); 3202 cls.set_num_native_fields(field_count);
(...skipping 2282 matching lines...) Expand 10 before | Expand all | Expand 10 after
5464 5485
5465 5486
5466 void Function::ClearCode() const { 5487 void Function::ClearCode() const {
5467 ASSERT(Thread::Current()->IsMutatorThread()); 5488 ASSERT(Thread::Current()->IsMutatorThread());
5468 ASSERT((usage_counter() != 0) || (ic_data_array() == Array::null())); 5489 ASSERT((usage_counter() != 0) || (ic_data_array() == Array::null()));
5469 StorePointer(&raw_ptr()->unoptimized_code_, Code::null()); 5490 StorePointer(&raw_ptr()->unoptimized_code_, Code::null());
5470 SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); 5491 SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code()));
5471 } 5492 }
5472 5493
5473 5494
5495 void Function::EnsureHasCompiledUnoptimizedCode() const {
5496 Thread* thread = Thread::Current();
5497 Zone* zone = thread->zone();
5498 ASSERT(thread->IsMutatorThread());
5499
5500 const Error& error = Error::Handle(zone,
5501 Compiler::EnsureUnoptimizedCode(thread, *this));
5502 if (!error.IsNull()) {
5503 Exceptions::PropagateError(error);
5504 }
5505 }
5506
5507
5474 void Function::SwitchToUnoptimizedCode() const { 5508 void Function::SwitchToUnoptimizedCode() const {
5475 ASSERT(HasOptimizedCode()); 5509 ASSERT(HasOptimizedCode());
5476 Thread* thread = Thread::Current(); 5510 Thread* thread = Thread::Current();
5477 Isolate* isolate = thread->isolate(); 5511 Isolate* isolate = thread->isolate();
5478 Zone* zone = thread->zone(); 5512 Zone* zone = thread->zone();
5479 ASSERT(thread->IsMutatorThread()); 5513 ASSERT(thread->IsMutatorThread());
5480 const Code& current_code = Code::Handle(zone, CurrentCode()); 5514 const Code& current_code = Code::Handle(zone, CurrentCode());
5481 5515
5482 if (FLAG_trace_deoptimization_verbose) { 5516 if (FLAG_trace_deoptimization_verbose) {
5483 THR_Print("Disabling optimized code: '%s' entry: %#" Px "\n", 5517 THR_Print("Disabling optimized code: '%s' entry: %#" Px "\n",
5484 ToFullyQualifiedCString(), 5518 ToFullyQualifiedCString(),
5485 current_code.EntryPoint()); 5519 current_code.EntryPoint());
5486 } 5520 }
5487 current_code.DisableDartCode(); 5521 current_code.DisableDartCode();
5488 const Error& error = Error::Handle(zone, 5522 const Error& error = Error::Handle(zone,
5489 Compiler::EnsureUnoptimizedCode(thread, *this)); 5523 Compiler::EnsureUnoptimizedCode(thread, *this));
5490 if (!error.IsNull()) { 5524 if (!error.IsNull()) {
5491 Exceptions::PropagateError(error); 5525 Exceptions::PropagateError(error);
5492 } 5526 }
5493 const Code& unopt_code = Code::Handle(zone, unoptimized_code()); 5527 const Code& unopt_code = Code::Handle(zone, unoptimized_code());
5494 AttachCode(unopt_code); 5528 AttachCode(unopt_code);
5495 unopt_code.Enable(); 5529 unopt_code.Enable();
5496 isolate->TrackDeoptimizedCode(current_code); 5530 isolate->TrackDeoptimizedCode(current_code);
5497 } 5531 }
5498 5532
5499 5533
5534 void Function::SwitchToLazyCompiledUnoptimizedCode() const {
5535 if (!HasOptimizedCode()) {
5536 return;
5537 }
5538
5539 Thread* thread = Thread::Current();
5540 Zone* zone = thread->zone();
5541 ASSERT(thread->IsMutatorThread());
5542
5543 const Code& current_code = Code::Handle(zone, CurrentCode());
5544 TIR_Print("Disabling optimized code for %s\n", ToCString());
5545 current_code.DisableDartCode();
5546
5547 const Code& unopt_code = Code::Handle(zone, unoptimized_code());
5548 if (unopt_code.IsNull()) {
5549 // Set the lazy compile code.
5550 TIR_Print("Switched to lazy compile stub for %s\n", ToCString());
5551 SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code()));
5552 return;
5553 }
5554
5555 TIR_Print("Switched to unoptimized code for %s\n", ToCString());
5556
5557 AttachCode(unopt_code);
5558 unopt_code.Enable();
5559 }
5560
5561
5500 void Function::set_unoptimized_code(const Code& value) const { 5562 void Function::set_unoptimized_code(const Code& value) const {
5501 ASSERT(Thread::Current()->IsMutatorThread()); 5563 ASSERT(Thread::Current()->IsMutatorThread());
5502 ASSERT(value.IsNull() || !value.is_optimized()); 5564 ASSERT(value.IsNull() || !value.is_optimized());
5503 StorePointer(&raw_ptr()->unoptimized_code_, value.raw()); 5565 StorePointer(&raw_ptr()->unoptimized_code_, value.raw());
5504 } 5566 }
5505 5567
5506 5568
5507 RawContextScope* Function::context_scope() const { 5569 RawContextScope* Function::context_scope() const {
5508 if (IsClosureFunction()) { 5570 if (IsClosureFunction()) {
5509 const Object& obj = Object::Handle(raw_ptr()->data_); 5571 const Object& obj = Object::Handle(raw_ptr()->data_);
(...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after
7054 if (raw_ptr()->owner_->IsClass()) { 7116 if (raw_ptr()->owner_->IsClass()) {
7055 return Class::RawCast(raw_ptr()->owner_); 7117 return Class::RawCast(raw_ptr()->owner_);
7056 } 7118 }
7057 const Object& obj = Object::Handle(raw_ptr()->owner_); 7119 const Object& obj = Object::Handle(raw_ptr()->owner_);
7058 ASSERT(obj.IsPatchClass()); 7120 ASSERT(obj.IsPatchClass());
7059 return PatchClass::Cast(obj).origin_class(); 7121 return PatchClass::Cast(obj).origin_class();
7060 } 7122 }
7061 7123
7062 7124
7063 RawScript* Function::script() const { 7125 RawScript* Function::script() const {
7126 // NOTE(turnidge): If you update this function, you probably want to
7127 // update Class::PatchFieldsAndFunctions() at the same time.
7064 if (token_pos() == TokenPosition::kMinSource) { 7128 if (token_pos() == TokenPosition::kMinSource) {
7065 // Testing for position 0 is an optimization that relies on temporary 7129 // Testing for position 0 is an optimization that relies on temporary
7066 // eval functions having token position 0. 7130 // eval functions having token position 0.
7067 const Script& script = Script::Handle(eval_script()); 7131 const Script& script = Script::Handle(eval_script());
7068 if (!script.IsNull()) { 7132 if (!script.IsNull()) {
7069 return script.raw(); 7133 return script.raw();
7070 } 7134 }
7071 } 7135 }
7072 if (IsClosureFunction()) { 7136 if (IsClosureFunction()) {
7073 return Function::Handle(parent_function()).script(); 7137 return Function::Handle(parent_function()).script();
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
7531 const Object& obj = Object::Handle(field.raw_ptr()->owner_); 7595 const Object& obj = Object::Handle(field.raw_ptr()->owner_);
7532 if (obj.IsClass()) { 7596 if (obj.IsClass()) {
7533 return Class::Cast(obj).raw(); 7597 return Class::Cast(obj).raw();
7534 } 7598 }
7535 ASSERT(obj.IsPatchClass()); 7599 ASSERT(obj.IsPatchClass());
7536 return PatchClass::Cast(obj).origin_class(); 7600 return PatchClass::Cast(obj).origin_class();
7537 } 7601 }
7538 7602
7539 7603
7540 RawScript* Field::Script() const { 7604 RawScript* Field::Script() const {
7605 // NOTE(turnidge): If you update this function, you probably want to
7606 // update Class::PatchFieldsAndFunctions() at the same time.
7541 const Field& field = Field::Handle(Original()); 7607 const Field& field = Field::Handle(Original());
7542 ASSERT(field.IsOriginal()); 7608 ASSERT(field.IsOriginal());
7543 const Object& obj = Object::Handle(field.raw_ptr()->owner_); 7609 const Object& obj = Object::Handle(field.raw_ptr()->owner_);
7544 if (obj.IsClass()) { 7610 if (obj.IsClass()) {
7545 return Class::Cast(obj).script(); 7611 return Class::Cast(obj).script();
7546 } 7612 }
7547 ASSERT(obj.IsPatchClass()); 7613 ASSERT(obj.IsPatchClass());
7548 return PatchClass::Cast(obj).script(); 7614 return PatchClass::Cast(obj).script();
7549 } 7615 }
7550 7616
(...skipping 11 matching lines...) Expand all
7562 7628
7563 RawField* Field::New() { 7629 RawField* Field::New() {
7564 ASSERT(Object::field_class() != Class::null()); 7630 ASSERT(Object::field_class() != Class::null());
7565 RawObject* raw = Object::Allocate(Field::kClassId, 7631 RawObject* raw = Object::Allocate(Field::kClassId,
7566 Field::InstanceSize(), 7632 Field::InstanceSize(),
7567 Heap::kOld); 7633 Heap::kOld);
7568 return reinterpret_cast<RawField*>(raw); 7634 return reinterpret_cast<RawField*>(raw);
7569 } 7635 }
7570 7636
7571 7637
7572 RawField* Field::New(const String& name, 7638 void Field::InitializeNew(const Field& result,
7573 bool is_static, 7639 const String& name,
7574 bool is_final, 7640 bool is_static,
7575 bool is_const, 7641 bool is_final,
7576 bool is_reflectable, 7642 bool is_const,
7577 const Class& owner, 7643 bool is_reflectable,
7578 const AbstractType& type, 7644 const Object& owner,
7579 TokenPosition token_pos) { 7645 TokenPosition token_pos) {
7580 ASSERT(!owner.IsNull());
7581 const Field& result = Field::Handle(Field::New());
7582 result.set_name(name); 7646 result.set_name(name);
7583 result.set_is_static(is_static); 7647 result.set_is_static(is_static);
7584 if (!is_static) { 7648 if (!is_static) {
7585 result.SetOffset(0); 7649 result.SetOffset(0);
7586 } 7650 }
7587 result.set_is_final(is_final); 7651 result.set_is_final(is_final);
7588 result.set_is_const(is_const); 7652 result.set_is_const(is_const);
7589 result.set_is_reflectable(is_reflectable); 7653 result.set_is_reflectable(is_reflectable);
7590 result.set_is_double_initialized(false); 7654 result.set_is_double_initialized(false);
7591 result.set_owner(owner); 7655 result.set_owner(owner);
7592 result.SetFieldType(type);
7593 result.set_token_pos(token_pos); 7656 result.set_token_pos(token_pos);
7594 result.set_has_initializer(false); 7657 result.set_has_initializer(false);
7595 result.set_is_unboxing_candidate(true); 7658 result.set_is_unboxing_candidate(true);
7596 result.set_guarded_cid(FLAG_use_field_guards ? kIllegalCid : kDynamicCid); 7659 Isolate* isolate = Isolate::Current();
7597 result.set_is_nullable(FLAG_use_field_guards ? false : true); 7660
7661 // Use field guards if they are enabled and the isolate has never reloaded.
7662 // TODO(johnmccutchan): The reload case assumes the worst case (everything is
7663 // dynamic and possibly null). Attempt to relax this later.
7664 const bool use_field_guards =
7665 FLAG_use_field_guards && !isolate->HasAttemptedReload();
7666 result.set_guarded_cid(use_field_guards ? kIllegalCid : kDynamicCid);
7667 result.set_is_nullable(use_field_guards ? false : true);
7598 result.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); 7668 result.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
7599 // Presently, we only attempt to remember the list length for final fields. 7669 // Presently, we only attempt to remember the list length for final fields.
7600 if (is_final && FLAG_use_field_guards) { 7670 if (is_final && use_field_guards) {
7601 result.set_guarded_list_length(Field::kUnknownFixedLength); 7671 result.set_guarded_list_length(Field::kUnknownFixedLength);
7602 } else { 7672 } else {
7603 result.set_guarded_list_length(Field::kNoFixedLength); 7673 result.set_guarded_list_length(Field::kNoFixedLength);
7604 } 7674 }
7675 }
7676
7677
7678 RawField* Field::New(const String& name,
7679 bool is_static,
7680 bool is_final,
7681 bool is_const,
7682 bool is_reflectable,
7683 const Class& owner,
7684 const AbstractType& type,
7685 TokenPosition token_pos) {
7686 ASSERT(!owner.IsNull());
7687 const Field& result = Field::Handle(Field::New());
7688 InitializeNew(result,
7689 name,
7690 is_static,
7691 is_final,
7692 is_const,
7693 is_reflectable,
7694 owner,
7695 token_pos);
7696 result.SetFieldType(type);
7605 return result.raw(); 7697 return result.raw();
7606 } 7698 }
7607 7699
7608 7700
7609 RawField* Field::NewTopLevel(const String& name, 7701 RawField* Field::NewTopLevel(const String& name,
7610 bool is_final, 7702 bool is_final,
7611 bool is_const, 7703 bool is_const,
7612 const Object& owner, 7704 const Object& owner,
7613 TokenPosition token_pos) { 7705 TokenPosition token_pos) {
7614 ASSERT(!owner.IsNull()); 7706 ASSERT(!owner.IsNull());
7615 const Field& result = Field::Handle(Field::New()); 7707 const Field& result = Field::Handle(Field::New());
7616 result.set_name(name); 7708 InitializeNew(result,
7617 result.set_is_static(true); 7709 name,
7618 result.set_is_final(is_final); 7710 true, /* is_static */
7619 result.set_is_const(is_const); 7711 is_final,
7620 result.set_is_reflectable(true); 7712 is_const,
7621 result.set_is_double_initialized(false); 7713 true, /* is_reflectable */
7622 result.set_owner(owner); 7714 owner,
7623 result.set_token_pos(token_pos); 7715 token_pos);
7624 result.set_has_initializer(false);
7625 result.set_is_unboxing_candidate(true);
7626 result.set_guarded_cid(FLAG_use_field_guards ? kIllegalCid : kDynamicCid);
7627 result.set_is_nullable(FLAG_use_field_guards ? false : true);
7628 result.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
7629 // Presently, we only attempt to remember the list length for final fields.
7630 if (is_final && FLAG_use_field_guards) {
7631 result.set_guarded_list_length(Field::kUnknownFixedLength);
7632 } else {
7633 result.set_guarded_list_length(Field::kNoFixedLength);
7634 }
7635 return result.raw(); 7716 return result.raw();
7636 } 7717 }
7637 7718
7638 7719
7639 RawField* Field::Clone(const Class& new_owner) const { 7720 RawField* Field::Clone(const Class& new_owner) const {
7640 Field& clone = Field::Handle(); 7721 Field& clone = Field::Handle();
7641 clone ^= Object::Clone(*this, Heap::kOld); 7722 clone ^= Object::Clone(*this, Heap::kOld);
7642 const Class& owner = Class::Handle(this->Owner()); 7723 const Class& owner = Class::Handle(this->Owner());
7643 const PatchClass& clone_owner = 7724 const PatchClass& clone_owner =
7644 PatchClass::Handle(PatchClass::New(new_owner, owner)); 7725 PatchClass::Handle(PatchClass::New(new_owner, owner));
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
8093 if (UpdateGuardedCidAndLength(value)) { 8174 if (UpdateGuardedCidAndLength(value)) {
8094 if (FLAG_trace_field_guards) { 8175 if (FLAG_trace_field_guards) {
8095 THR_Print(" => %s\n", GuardedPropertiesAsCString()); 8176 THR_Print(" => %s\n", GuardedPropertiesAsCString());
8096 } 8177 }
8097 8178
8098 DeoptimizeDependentCode(); 8179 DeoptimizeDependentCode();
8099 } 8180 }
8100 } 8181 }
8101 8182
8102 8183
8184 void Field::ForceDynamicGuardedCidAndLength() const {
8185 // Assume nothing about this field.
8186 set_is_unboxing_candidate(false);
8187 set_guarded_cid(kDynamicCid);
8188 set_is_nullable(true);
8189 set_guarded_list_length(Field::kNoFixedLength);
8190 set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
8191 // Drop any code that relied on the above assumptions.
8192 DeoptimizeDependentCode();
8193 }
8194
8195
8103 void LiteralToken::set_literal(const String& literal) const { 8196 void LiteralToken::set_literal(const String& literal) const {
8104 StorePointer(&raw_ptr()->literal_, literal.raw()); 8197 StorePointer(&raw_ptr()->literal_, literal.raw());
8105 } 8198 }
8106 8199
8107 8200
8108 void LiteralToken::set_value(const Object& value) const { 8201 void LiteralToken::set_value(const Object& value) const {
8109 StorePointer(&raw_ptr()->value_, value.raw()); 8202 StorePointer(&raw_ptr()->value_, value.raw());
8110 } 8203 }
8111 8204
8112 8205
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
8920 void Script::set_source(const String& value) const { 9013 void Script::set_source(const String& value) const {
8921 StorePointer(&raw_ptr()->source_, value.raw()); 9014 StorePointer(&raw_ptr()->source_, value.raw());
8922 } 9015 }
8923 9016
8924 9017
8925 void Script::set_kind(RawScript::Kind value) const { 9018 void Script::set_kind(RawScript::Kind value) const {
8926 StoreNonPointer(&raw_ptr()->kind_, value); 9019 StoreNonPointer(&raw_ptr()->kind_, value);
8927 } 9020 }
8928 9021
8929 9022
9023 void Script::set_load_timestamp(int64_t value) const {
9024 StoreNonPointer(&raw_ptr()->load_timestamp_, value);
9025 }
9026
9027
8930 void Script::set_tokens(const TokenStream& value) const { 9028 void Script::set_tokens(const TokenStream& value) const {
8931 StorePointer(&raw_ptr()->tokens_, value.raw()); 9029 StorePointer(&raw_ptr()->tokens_, value.raw());
8932 } 9030 }
8933 9031
8934 9032
8935 void Script::Tokenize(const String& private_key, 9033 void Script::Tokenize(const String& private_key,
8936 bool use_shared_tokens) const { 9034 bool use_shared_tokens) const {
8937 Thread* thread = Thread::Current(); 9035 Thread* thread = Thread::Current();
8938 Zone* zone = thread->zone(); 9036 Zone* zone = thread->zone();
8939 const TokenStream& tkns = TokenStream::Handle(zone, tokens()); 9037 const TokenStream& tkns = TokenStream::Handle(zone, tokens());
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
9173 9271
9174 RawScript* Script::New(const String& url, 9272 RawScript* Script::New(const String& url,
9175 const String& source, 9273 const String& source,
9176 RawScript::Kind kind) { 9274 RawScript::Kind kind) {
9177 Thread* thread = Thread::Current(); 9275 Thread* thread = Thread::Current();
9178 Zone* zone = thread->zone(); 9276 Zone* zone = thread->zone();
9179 const Script& result = Script::Handle(zone, Script::New()); 9277 const Script& result = Script::Handle(zone, Script::New());
9180 result.set_url(String::Handle(zone, Symbols::New(thread, url))); 9278 result.set_url(String::Handle(zone, Symbols::New(thread, url)));
9181 result.set_source(source); 9279 result.set_source(source);
9182 result.set_kind(kind); 9280 result.set_kind(kind);
9281 result.set_load_timestamp(FLAG_remove_script_timestamps_for_test
9282 ? 0 : OS::GetCurrentTimeMillis());
9183 result.SetLocationOffset(0, 0); 9283 result.SetLocationOffset(0, 0);
9184 return result.raw(); 9284 return result.raw();
9185 } 9285 }
9186 9286
9187 9287
9188 const char* Script::ToCString() const { 9288 const char* Script::ToCString() const {
9189 return "Script"; 9289 const String& name = String::Handle(url());
9290 return OS::SCreate(Thread::Current()->zone(), "Script(%s)", name.ToCString());
9190 } 9291 }
9191 9292
9192 9293
9193 RawLibrary* Script::FindLibrary() const { 9294 RawLibrary* Script::FindLibrary() const {
9194 Thread* thread = Thread::Current(); 9295 Thread* thread = Thread::Current();
9195 Zone* zone = thread->zone(); 9296 Zone* zone = thread->zone();
9196 Isolate* isolate = thread->isolate(); 9297 Isolate* isolate = thread->isolate();
9197 const GrowableObjectArray& libs = GrowableObjectArray::Handle(zone, 9298 const GrowableObjectArray& libs = GrowableObjectArray::Handle(zone,
9198 isolate->object_store()->libraries()); 9299 isolate->object_store()->libraries());
9199 Library& lib = Library::Handle(zone); 9300 Library& lib = Library::Handle(zone);
(...skipping 3469 matching lines...) Expand 10 before | Expand all | Expand 10 after
12669 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) { 12770 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) {
12670 return num_args + 1 /* target function*/ + 1 /* frequency */; 12771 return num_args + 1 /* target function*/ + 1 /* frequency */;
12671 } 12772 }
12672 12773
12673 12774
12674 intptr_t ICData::TestEntryLength() const { 12775 intptr_t ICData::TestEntryLength() const {
12675 return TestEntryLengthFor(NumArgsTested()); 12776 return TestEntryLengthFor(NumArgsTested());
12676 } 12777 }
12677 12778
12678 12779
12780 intptr_t ICData::Length() const {
12781 return (Smi::Value(ic_data()->ptr()->length_) / TestEntryLength());
12782 }
12783
12784
12679 intptr_t ICData::NumberOfChecks() const { 12785 intptr_t ICData::NumberOfChecks() const {
12680 // Do not count the sentinel; 12786 const intptr_t length = Length();
12681 return (Smi::Value(ic_data()->ptr()->length_) / TestEntryLength()) - 1; 12787 for (intptr_t i = 0; i < length; i++) {
12788 if (IsSentinelAt(i)) {
12789 return i;
12790 }
12791 }
Florian Schneider 2016/05/18 09:36:56 This approach does not work with background compil
12792 UNREACHABLE();
12793 return -1;
12682 } 12794 }
12683 12795
12684 12796
12685 // Discounts any checks with usage of zero. 12797 // Discounts any checks with usage of zero.
12686 intptr_t ICData::NumberOfUsedChecks() const { 12798 intptr_t ICData::NumberOfUsedChecks() const {
12687 intptr_t n = NumberOfChecks(); 12799 intptr_t n = NumberOfChecks();
12688 if (n == 0) { 12800 if (n == 0) {
12689 return 0; 12801 return 0;
12690 } 12802 }
12691 intptr_t count = 0; 12803 intptr_t count = 0;
(...skipping 16 matching lines...) Expand all
12708 12820
12709 #if defined(DEBUG) 12821 #if defined(DEBUG)
12710 // Used in asserts to verify that a check is not added twice. 12822 // Used in asserts to verify that a check is not added twice.
12711 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { 12823 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const {
12712 const intptr_t len = NumberOfChecks(); 12824 const intptr_t len = NumberOfChecks();
12713 for (intptr_t i = 0; i < len; i++) { 12825 for (intptr_t i = 0; i < len; i++) {
12714 GrowableArray<intptr_t> class_ids; 12826 GrowableArray<intptr_t> class_ids;
12715 GetClassIdsAt(i, &class_ids); 12827 GetClassIdsAt(i, &class_ids);
12716 bool matches = true; 12828 bool matches = true;
12717 for (intptr_t k = 0; k < class_ids.length(); k++) { 12829 for (intptr_t k = 0; k < class_ids.length(); k++) {
12830 ASSERT(class_ids[k] != kIllegalCid);
12718 if (class_ids[k] != cids[k]) { 12831 if (class_ids[k] != cids[k]) {
12719 matches = false; 12832 matches = false;
12720 break; 12833 break;
12721 } 12834 }
12722 } 12835 }
12723 if (matches) { 12836 if (matches) {
12724 return true; 12837 return true;
12725 } 12838 }
12726 } 12839 }
12727 return false; 12840 return false;
12728 } 12841 }
12729 #endif // DEBUG 12842 #endif // DEBUG
12730 12843
12731 12844
12845 void ICData::WriteSentinelAt(intptr_t index) const {
12846 const intptr_t len = Length();
12847 ASSERT(index >= 0);
12848 ASSERT(index < len);
12849 Array& data = Array::Handle(ic_data());
12850 const intptr_t start = index * TestEntryLength();
12851 const intptr_t end = start + TestEntryLength();
12852 for (intptr_t i = start; i < end; i++) {
12853 data.SetAt(i, smi_illegal_cid());
12854 }
12855 }
12856
12857
12858 void ICData::ClearCountAt(intptr_t index) const {
12859 const intptr_t len = NumberOfChecks();
12860 ASSERT(index >= 0);
12861 ASSERT(index < len);
12862 SetCountAt(index, 0);
12863 }
12864
12865
12866 void ICData::ClearWithSentinel() const {
12867 if (IsImmutable()) {
12868 return;
12869 }
12870 // Write the sentinel value into all entries except the first one.
12871 const intptr_t len = Length();
12872 if (len == 0) {
12873 return;
12874 }
12875 // The final entry is always the sentinel.
12876 ASSERT(IsSentinelAt(len - 1));
12877 for (intptr_t i = len - 1; i > 0; i--) {
12878 WriteSentinelAt(i);
12879 }
12880 if (NumArgsTested() != 2) {
12881 // Not the smi fast path case, write sentinel to first one and exit.
12882 WriteSentinelAt(0);
12883 return;
12884 }
12885 if (IsSentinelAt(0)) {
12886 return;
12887 }
12888 Zone* zone = Thread::Current()->zone();
12889 const String& name = String::Handle(target_name());
12890 const Class& smi_class = Class::Handle(Smi::Class());
12891 const Function& smi_op_target =
12892 Function::Handle(Resolver::ResolveDynamicAnyArgs(zone, smi_class, name));
12893 GrowableArray<intptr_t> class_ids(2);
12894 Function& target = Function::Handle();
12895 GetCheckAt(0, &class_ids, &target);
12896 if ((target.raw() == smi_op_target.raw()) &&
12897 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
12898 // The smi fast path case, preserve the initial entry but reset the count.
12899 ClearCountAt(0);
12900 return;
12901 }
12902 WriteSentinelAt(0);
12903 }
12904
12905
12906 void ICData::ClearAndSetStaticTarget(const Function& func) const {
12907 if (IsImmutable()) {
12908 return;
12909 }
12910 const intptr_t len = Length();
12911 if (len == 0) {
12912 return;
12913 }
12914 // The final entry is always the sentinel.
12915 ASSERT(IsSentinelAt(len - 1));
12916 if (NumArgsTested() == 0) {
12917 // No type feedback is being collected.
12918 const Array& data = Array::Handle(ic_data());
12919 // Static calls with no argument checks hold only one target and the
12920 // sentinel value.
12921 ASSERT(len == 2);
12922 // Static calls with no argument checks only need two words.
12923 ASSERT(TestEntryLength() == 2);
12924 // Set the target.
12925 data.SetAt(0, func);
12926 // Set count to 0 as this is called during compilation, before the
12927 // call has been executed.
12928 const Smi& value = Smi::Handle(Smi::New(0));
12929 data.SetAt(1, value);
12930 } else {
12931 // Type feedback on arguments is being collected.
12932 const Array& data = Array::Handle(ic_data());
12933
12934 // Fill all but the first entry with the sentinel.
12935 for (intptr_t i = len - 1; i > 0; i--) {
12936 WriteSentinelAt(i);
12937 }
12938 // Rewrite the dummy entry.
12939 const Smi& object_cid = Smi::Handle(Smi::New(kObjectCid));
12940 for (intptr_t i = 0; i < NumArgsTested(); i++) {
12941 data.SetAt(i, object_cid);
12942 }
12943 data.SetAt(NumArgsTested(), func);
12944 const Smi& value = Smi::Handle(Smi::New(0));
12945 data.SetAt(NumArgsTested() + 1, value);
12946 }
12947 }
12948
12949
12950 // Add an initial Smi/Smi check with count 0.
12951 bool ICData::AddSmiSmiCheckForFastSmiStubs() const {
12952 bool is_smi_two_args_op = false;
12953
12954 ASSERT(NumArgsTested() == 2);
12955 const String& name = String::Handle(target_name());
12956 const Class& smi_class = Class::Handle(Smi::Class());
12957 Zone* zone = Thread::Current()->zone();
12958 const Function& smi_op_target =
12959 Function::Handle(Resolver::ResolveDynamicAnyArgs(zone, smi_class, name));
12960 if (NumberOfChecks() == 0) {
12961 GrowableArray<intptr_t> class_ids(2);
12962 class_ids.Add(kSmiCid);
12963 class_ids.Add(kSmiCid);
12964 AddCheck(class_ids, smi_op_target);
12965 // 'AddCheck' sets the initial count to 1.
12966 SetCountAt(0, 0);
12967 is_smi_two_args_op = true;
12968 } else if (NumberOfChecks() == 1) {
12969 GrowableArray<intptr_t> class_ids(2);
12970 Function& target = Function::Handle();
12971 GetCheckAt(0, &class_ids, &target);
12972 if ((target.raw() == smi_op_target.raw()) &&
12973 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
12974 is_smi_two_args_op = true;
12975 }
12976 }
12977 return is_smi_two_args_op;
12978 }
12979
12980
12732 // Used for unoptimized static calls when no class-ids are checked. 12981 // Used for unoptimized static calls when no class-ids are checked.
12733 void ICData::AddTarget(const Function& target) const { 12982 void ICData::AddTarget(const Function& target) const {
12734 ASSERT(!target.IsNull()); 12983 ASSERT(!target.IsNull());
12735 if (NumArgsTested() > 0) { 12984 if (NumArgsTested() > 0) {
12736 // Create a fake cid entry, so that we can store the target. 12985 // Create a fake cid entry, so that we can store the target.
12737 if (NumArgsTested() == 1) { 12986 if (NumArgsTested() == 1) {
12738 AddReceiverCheck(kObjectCid, target, 1); 12987 AddReceiverCheck(kObjectCid, target, 1);
12739 } else { 12988 } else {
12740 GrowableArray<intptr_t> class_ids(NumArgsTested()); 12989 GrowableArray<intptr_t> class_ids(NumArgsTested());
12741 for (intptr_t i = 0; i < NumArgsTested(); i++) { 12990 for (intptr_t i = 0; i < NumArgsTested(); i++) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
12791 // Replace dummy entry. 13040 // Replace dummy entry.
12792 Smi& value = Smi::Handle(); 13041 Smi& value = Smi::Handle();
12793 for (intptr_t i = 0; i < NumArgsTested(); i++) { 13042 for (intptr_t i = 0; i < NumArgsTested(); i++) {
12794 ASSERT(class_ids[i] != kIllegalCid); 13043 ASSERT(class_ids[i] != kIllegalCid);
12795 value = Smi::New(class_ids[i]); 13044 value = Smi::New(class_ids[i]);
12796 data.SetAt(i, value); 13045 data.SetAt(i, value);
12797 } 13046 }
12798 return; 13047 return;
12799 } 13048 }
12800 } 13049 }
12801 const intptr_t new_len = data.Length() + TestEntryLength(); 13050 intptr_t index = -1;
12802 data = Array::Grow(data, new_len, Heap::kOld); 13051 data = FindFreeIndex(&index);
12803 WriteSentinel(data, TestEntryLength()); 13052 ASSERT(!data.IsNull());
12804 intptr_t data_pos = old_num * TestEntryLength(); 13053 intptr_t data_pos = index * TestEntryLength();
12805 Smi& value = Smi::Handle(); 13054 Smi& value = Smi::Handle();
12806 for (intptr_t i = 0; i < class_ids.length(); i++) { 13055 for (intptr_t i = 0; i < class_ids.length(); i++) {
12807 // kIllegalCid is used as terminating value, do not add it. 13056 // kIllegalCid is used as terminating value, do not add it.
12808 ASSERT(class_ids[i] != kIllegalCid); 13057 ASSERT(class_ids[i] != kIllegalCid);
12809 value = Smi::New(class_ids[i]); 13058 value = Smi::New(class_ids[i]);
12810 data.SetAt(data_pos++, value); 13059 data.SetAt(data_pos++, value);
12811 } 13060 }
12812 ASSERT(!target.IsNull()); 13061 ASSERT(!target.IsNull());
12813 data.SetAt(data_pos++, target); 13062 data.SetAt(data_pos++, target);
12814 value = Smi::New(1); 13063 value = Smi::New(1);
12815 data.SetAt(data_pos, value); 13064 data.SetAt(data_pos, value);
12816 // Multithreaded access to ICData requires setting of array to be the last 13065 // Multithreaded access to ICData requires setting of array to be the last
12817 // operation. 13066 // operation.
12818 set_ic_data_array(data); 13067 set_ic_data_array(data);
12819 } 13068 }
12820 13069
12821 13070
13071 RawArray* ICData::FindFreeIndex(intptr_t* index) const {
13072 // The final entry is always the sentinel value, don't consider it
13073 // when searching.
13074 const intptr_t len = Length() - 1;
13075 Array& data = Array::Handle(ic_data());
13076 *index = len;
13077 for (intptr_t i = 0; i < len; i++) {
13078 if (IsSentinelAt(i)) {
13079 *index = i;
13080 break;
13081 }
13082 }
13083 if (*index < len) {
13084 // We've found a free slot.
13085 return data.raw();
13086 }
13087 // Append case.
13088 ASSERT(*index == len);
13089 ASSERT(*index >= 0);
13090 // Grow array.
13091 const intptr_t new_len = data.Length() + TestEntryLength();
13092 data = Array::Grow(data, new_len, Heap::kOld);
13093 WriteSentinel(data, TestEntryLength());
13094 return data.raw();
13095 }
13096
13097
13098 void ICData::DebugDump() const {
13099 const Function& owner = Function::Handle(Owner());
13100 THR_Print("ICData::DebugDump\n");
13101 THR_Print("Owner = %s [deopt=%" Pd "]\n", owner.ToCString(), deopt_id());
13102 THR_Print("NumArgsTested = %" Pd "\n", NumArgsTested());
13103 THR_Print("Length = %" Pd "\n", Length());
13104 THR_Print("NumberOfChecks = %" Pd "\n", NumberOfChecks());
13105
13106 GrowableArray<intptr_t> class_ids;
13107 for (intptr_t i = 0; i < NumberOfChecks(); i++) {
13108 THR_Print("Check[%" Pd "]:", i);
13109 GetClassIdsAt(i, &class_ids);
13110 for (intptr_t c = 0; c < class_ids.length(); c++) {
13111 THR_Print(" %" Pd "", class_ids[c]);
13112 }
13113 THR_Print("--- %" Pd " hits\n", GetCountAt(i));
13114 }
13115 }
13116
13117
13118 void ICData::ValidateSentinelLocations() const {
13119 }
13120
13121
12822 void ICData::AddReceiverCheck(intptr_t receiver_class_id, 13122 void ICData::AddReceiverCheck(intptr_t receiver_class_id,
12823 const Function& target, 13123 const Function& target,
12824 intptr_t count) const { 13124 intptr_t count) const {
12825 #if defined(DEBUG) 13125 #if defined(DEBUG)
12826 GrowableArray<intptr_t> class_ids(1); 13126 GrowableArray<intptr_t> class_ids(1);
12827 class_ids.Add(receiver_class_id); 13127 class_ids.Add(receiver_class_id);
12828 ASSERT(!HasCheck(class_ids)); 13128 ASSERT(!HasCheck(class_ids));
12829 #endif // DEBUG 13129 #endif // DEBUG
12830 ASSERT(!target.IsNull()); 13130 ASSERT(!target.IsNull());
12831 ASSERT(NumArgsTested() == 1); // Otherwise use 'AddCheck'. 13131 ASSERT(NumArgsTested() == 1); // Otherwise use 'AddCheck'.
12832 ASSERT(receiver_class_id != kIllegalCid); 13132 ASSERT(receiver_class_id != kIllegalCid);
12833 13133
12834 const intptr_t old_num = NumberOfChecks(); 13134 intptr_t index = -1;
12835 Array& data = Array::Handle(ic_data()); 13135 Array& data = Array::Handle(FindFreeIndex(&index));
12836 const intptr_t new_len = data.Length() + TestEntryLength(); 13136 intptr_t data_pos = index * TestEntryLength();
12837 data = Array::Grow(data, new_len, Heap::kOld);
12838 WriteSentinel(data, TestEntryLength());
12839 intptr_t data_pos = old_num * TestEntryLength();
12840 if ((receiver_class_id == kSmiCid) && (data_pos > 0)) { 13137 if ((receiver_class_id == kSmiCid) && (data_pos > 0)) {
12841 ASSERT(GetReceiverClassIdAt(0) != kSmiCid); 13138 ASSERT(GetReceiverClassIdAt(0) != kSmiCid);
12842 // Move class occupying position 0 to the data_pos. 13139 // Move class occupying position 0 to the data_pos.
12843 for (intptr_t i = 0; i < TestEntryLength(); i++) { 13140 for (intptr_t i = 0; i < TestEntryLength(); i++) {
12844 data.SetAt(data_pos + i, Object::Handle(data.At(i))); 13141 data.SetAt(data_pos + i, Object::Handle(data.At(i)));
12845 } 13142 }
12846 // Insert kSmiCid in position 0. 13143 // Insert kSmiCid in position 0.
12847 data_pos = 0; 13144 data_pos = 0;
12848 } 13145 }
12849 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); 13146 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id)));
(...skipping 24 matching lines...) Expand all
12874 class_ids->Clear(); 13171 class_ids->Clear();
12875 const Array& data = Array::Handle(ic_data()); 13172 const Array& data = Array::Handle(ic_data());
12876 intptr_t data_pos = index * TestEntryLength(); 13173 intptr_t data_pos = index * TestEntryLength();
12877 for (intptr_t i = 0; i < NumArgsTested(); i++) { 13174 for (intptr_t i = 0; i < NumArgsTested(); i++) {
12878 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); 13175 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
12879 } 13176 }
12880 (*target) ^= data.At(data_pos++); 13177 (*target) ^= data.At(data_pos++);
12881 } 13178 }
12882 13179
12883 13180
13181 bool ICData::IsSentinelAt(intptr_t index) const {
13182 ASSERT(index < Length());
13183 const Array& data = Array::Handle(ic_data());
13184 const intptr_t entry_length = TestEntryLength();
13185 intptr_t data_pos = index * TestEntryLength();
13186 for (intptr_t i = 0; i < entry_length; i++) {
13187 if (data.At(data_pos++) != smi_illegal_cid().raw()) {
13188 return false;
13189 }
13190 }
13191 // The entry at |index| was filled with the value kIllegalCid.
13192 return true;
13193 }
13194
13195
12884 void ICData::GetClassIdsAt(intptr_t index, 13196 void ICData::GetClassIdsAt(intptr_t index,
12885 GrowableArray<intptr_t>* class_ids) const { 13197 GrowableArray<intptr_t>* class_ids) const {
12886 ASSERT(index < NumberOfChecks()); 13198 ASSERT(index < Length());
12887 ASSERT(class_ids != NULL); 13199 ASSERT(class_ids != NULL);
13200 ASSERT(!IsSentinelAt(index));
12888 class_ids->Clear(); 13201 class_ids->Clear();
12889 const Array& data = Array::Handle(ic_data()); 13202 const Array& data = Array::Handle(ic_data());
12890 intptr_t data_pos = index * TestEntryLength(); 13203 intptr_t data_pos = index * TestEntryLength();
12891 for (intptr_t i = 0; i < NumArgsTested(); i++) { 13204 for (intptr_t i = 0; i < NumArgsTested(); i++) {
12892 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); 13205 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
12893 } 13206 }
12894 } 13207 }
12895 13208
12896 13209
12897 void ICData::GetOneClassCheckAt(intptr_t index, 13210 void ICData::GetOneClassCheckAt(intptr_t index,
(...skipping 18 matching lines...) Expand all
12916 13229
12917 13230
12918 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const { 13231 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const {
12919 GrowableArray<intptr_t> class_ids; 13232 GrowableArray<intptr_t> class_ids;
12920 GetClassIdsAt(index, &class_ids); 13233 GetClassIdsAt(index, &class_ids);
12921 return class_ids[arg_nr]; 13234 return class_ids[arg_nr];
12922 } 13235 }
12923 13236
12924 13237
12925 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const { 13238 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const {
12926 ASSERT(index < NumberOfChecks()); 13239 ASSERT(index < Length());
13240 ASSERT(!IsSentinelAt(index));
12927 const intptr_t data_pos = index * TestEntryLength(); 13241 const intptr_t data_pos = index * TestEntryLength();
12928 NoSafepointScope no_safepoint; 13242 NoSafepointScope no_safepoint;
12929 RawArray* raw_data = ic_data(); 13243 RawArray* raw_data = ic_data();
12930 return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos])); 13244 return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos]));
12931 } 13245 }
12932 13246
12933 13247
12934 RawFunction* ICData::GetTargetAt(intptr_t index) const { 13248 RawFunction* ICData::GetTargetAt(intptr_t index) const {
12935 ASSERT(Isolate::Current()->compilation_allowed()); 13249 ASSERT(Isolate::Current()->compilation_allowed());
12936 const intptr_t data_pos = index * TestEntryLength() + NumArgsTested(); 13250 const intptr_t data_pos = index * TestEntryLength() + NumArgsTested();
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
13120 &Function::ZoneHandle(GetTargetAt(i)))); 13434 &Function::ZoneHandle(GetTargetAt(i))));
13121 } 13435 }
13122 } 13436 }
13123 aggregate.Sort(CidCount::HighestCountFirst); 13437 aggregate.Sort(CidCount::HighestCountFirst);
13124 13438
13125 ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested)); 13439 ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested));
13126 ASSERT(result.NumberOfChecks() == 0); 13440 ASSERT(result.NumberOfChecks() == 0);
13127 // Room for all entries and the sentinel. 13441 // Room for all entries and the sentinel.
13128 const intptr_t data_len = 13442 const intptr_t data_len =
13129 result.TestEntryLength() * (aggregate.length() + 1); 13443 result.TestEntryLength() * (aggregate.length() + 1);
13444 // Allocate the array but do not assign it to result until we have populated
13445 // it with the aggregate data and the terminating sentinel.
13130 const Array& data = Array::Handle(Array::New(data_len, Heap::kOld)); 13446 const Array& data = Array::Handle(Array::New(data_len, Heap::kOld));
13131 result.set_ic_data_array(data);
13132 ASSERT(result.NumberOfChecks() == aggregate.length());
13133
13134 intptr_t pos = 0; 13447 intptr_t pos = 0;
13135 for (intptr_t i = 0; i < aggregate.length(); i++) { 13448 for (intptr_t i = 0; i < aggregate.length(); i++) {
13136 data.SetAt(pos + 0, Smi::Handle(Smi::New(aggregate[i].cid))); 13449 data.SetAt(pos + 0, Smi::Handle(Smi::New(aggregate[i].cid)));
13137 data.SetAt(pos + TargetIndexFor(1), *aggregate[i].function); 13450 data.SetAt(pos + TargetIndexFor(1), *aggregate[i].function);
13138 data.SetAt(pos + CountIndexFor(1), 13451 data.SetAt(pos + CountIndexFor(1),
13139 Smi::Handle(Smi::New(aggregate[i].count))); 13452 Smi::Handle(Smi::New(aggregate[i].count)));
13140 13453
13141 pos += result.TestEntryLength(); 13454 pos += result.TestEntryLength();
13142 } 13455 }
13143 WriteSentinel(data, result.TestEntryLength()); 13456 WriteSentinel(data, result.TestEntryLength());
13144 result.set_ic_data_array(data); 13457 result.set_ic_data_array(data);
13458 ASSERT(result.NumberOfChecks() == aggregate.length());
13145 return result.raw(); 13459 return result.raw();
13146 } 13460 }
13147 13461
13148 13462
13149 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const { 13463 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const {
13150 if (NumberOfChecks() == 0) return false; 13464 if (NumberOfChecks() == 0) return false;
13151 Class& cls = Class::Handle(); 13465 Class& cls = Class::Handle();
13152 const intptr_t len = NumberOfChecks(); 13466 const intptr_t len = NumberOfChecks();
13153 for (intptr_t i = 0; i < len; i++) { 13467 for (intptr_t i = 0; i < len; i++) {
13154 if (IsUsedAt(i)) { 13468 if (IsUsedAt(i)) {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
13281 result.set_deopt_id(deopt_id); 13595 result.set_deopt_id(deopt_id);
13282 result.set_state_bits(0); 13596 result.set_state_bits(0);
13283 #if defined(TAG_IC_DATA) 13597 #if defined(TAG_IC_DATA)
13284 result.set_tag(-1); 13598 result.set_tag(-1);
13285 #endif 13599 #endif
13286 result.SetNumArgsTested(num_args_tested); 13600 result.SetNumArgsTested(num_args_tested);
13287 return result.raw(); 13601 return result.raw();
13288 } 13602 }
13289 13603
13290 13604
13605 bool ICData::IsImmutable() const {
13606 const Array& data = Array::Handle(ic_data());
13607 return data.IsImmutable();
13608 }
13609
13610
13611 void ICData::ResetData() const {
13612 // Number of array elements in one test entry.
13613 intptr_t len = TestEntryLength();
13614 // IC data array must be null terminated (sentinel entry).
13615 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld));
13616 set_ic_data_array(ic_data);
13617 WriteSentinel(ic_data, len);
13618 }
13619
13620
13291 RawICData* ICData::New() { 13621 RawICData* ICData::New() {
13292 ICData& result = ICData::Handle(); 13622 ICData& result = ICData::Handle();
13293 { 13623 {
13294 // IC data objects are long living objects, allocate them in old generation. 13624 // IC data objects are long living objects, allocate them in old generation.
13295 RawObject* raw = Object::Allocate(ICData::kClassId, 13625 RawObject* raw = Object::Allocate(ICData::kClassId,
13296 ICData::InstanceSize(), 13626 ICData::InstanceSize(),
13297 Heap::kOld); 13627 Heap::kOld);
13298 NoSafepointScope no_safepoint; 13628 NoSafepointScope no_safepoint;
13299 result ^= raw; 13629 result ^= raw;
13300 } 13630 }
(...skipping 2303 matching lines...) Expand 10 before | Expand all | Expand 10 after
15604 } 15934 }
15605 15935
15606 15936
15607 bool AbstractType::HasResolvedTypeClass() const { 15937 bool AbstractType::HasResolvedTypeClass() const {
15608 // AbstractType is an abstract class. 15938 // AbstractType is an abstract class.
15609 UNREACHABLE(); 15939 UNREACHABLE();
15610 return false; 15940 return false;
15611 } 15941 }
15612 15942
15613 15943
15944 classid_t AbstractType::type_class_id() const {
15945 // AbstractType is an abstract class.
15946 UNREACHABLE();
15947 return kIllegalCid;
15948 }
15949
15950
15614 RawClass* AbstractType::type_class() const { 15951 RawClass* AbstractType::type_class() const {
15615 // AbstractType is an abstract class. 15952 // AbstractType is an abstract class.
15616 UNREACHABLE(); 15953 UNREACHABLE();
15617 return Class::null(); 15954 return Class::null();
15618 } 15955 }
15619 15956
15620 15957
15621 RawUnresolvedClass* AbstractType::unresolved_class() const { 15958 RawUnresolvedClass* AbstractType::unresolved_class() const {
15622 // AbstractType is an abstract class. 15959 // AbstractType is an abstract class.
15623 UNREACHABLE(); 15960 UNREACHABLE();
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
16469 } 16806 }
16470 16807
16471 16808
16472 void Type::SetIsResolved() const { 16809 void Type::SetIsResolved() const {
16473 ASSERT(!IsResolved()); 16810 ASSERT(!IsResolved());
16474 set_type_state(RawType::kResolved); 16811 set_type_state(RawType::kResolved);
16475 } 16812 }
16476 16813
16477 16814
16478 bool Type::HasResolvedTypeClass() const { 16815 bool Type::HasResolvedTypeClass() const {
16479 return (raw_ptr()->type_class_->GetClassId() == kClassCid); 16816 return !raw_ptr()->type_class_id_->IsHeapObject();
16817 }
16818
16819
16820 classid_t Type::type_class_id() const {
16821 ASSERT(HasResolvedTypeClass());
16822 return Smi::Value(reinterpret_cast<RawSmi*>(raw_ptr()->type_class_id_));
16480 } 16823 }
16481 16824
16482 16825
16483 RawClass* Type::type_class() const { 16826 RawClass* Type::type_class() const {
16484 #ifdef DEBUG 16827 return Isolate::Current()->class_table()->At(type_class_id());
16485 ASSERT(HasResolvedTypeClass());
16486 Class& type_class = Class::Handle();
16487 type_class ^= raw_ptr()->type_class_;
16488 return type_class.raw();
16489 #else
16490 return reinterpret_cast<RawClass*>(raw_ptr()->type_class_);
16491 #endif
16492 } 16828 }
16493 16829
16494 16830
16495 RawUnresolvedClass* Type::unresolved_class() const { 16831 RawUnresolvedClass* Type::unresolved_class() const {
16496 #ifdef DEBUG 16832 #ifdef DEBUG
16497 ASSERT(!HasResolvedTypeClass()); 16833 ASSERT(!HasResolvedTypeClass());
16498 UnresolvedClass& unresolved_class = UnresolvedClass::Handle(); 16834 UnresolvedClass& unresolved_class = UnresolvedClass::Handle();
16499 unresolved_class ^= raw_ptr()->type_class_; 16835 unresolved_class ^= raw_ptr()->type_class_id_;
16500 ASSERT(!unresolved_class.IsNull()); 16836 ASSERT(!unresolved_class.IsNull());
16501 return unresolved_class.raw(); 16837 return unresolved_class.raw();
16502 #else 16838 #else
16503 ASSERT(!Object::Handle(raw_ptr()->type_class_).IsNull()); 16839 ASSERT(!Object::Handle(raw_ptr()->type_class_id_).IsNull());
16504 ASSERT(Object::Handle(raw_ptr()->type_class_).IsUnresolvedClass()); 16840 ASSERT(Object::Handle(raw_ptr()->type_class_id_).IsUnresolvedClass());
16505 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); 16841 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_id_);
16506 #endif 16842 #endif
16507 } 16843 }
16508 16844
16509 16845
16510 bool Type::IsInstantiated(TrailPtr trail) const { 16846 bool Type::IsInstantiated(TrailPtr trail) const {
16511 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { 16847 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) {
16512 return true; 16848 return true;
16513 } 16849 }
16514 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { 16850 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) {
16515 return false; 16851 return false;
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
17061 for (intptr_t i = sig_fun.num_fixed_parameters(); i < num_params; i++) { 17397 for (intptr_t i = sig_fun.num_fixed_parameters(); i < num_params; i++) {
17062 param_name = sig_fun.ParameterNameAt(i); 17398 param_name = sig_fun.ParameterNameAt(i);
17063 result = CombineHashes(result, param_name.Hash()); 17399 result = CombineHashes(result, param_name.Hash());
17064 } 17400 }
17065 } 17401 }
17066 } 17402 }
17067 return FinalizeHash(result); 17403 return FinalizeHash(result);
17068 } 17404 }
17069 17405
17070 17406
17071 void Type::set_type_class(const Object& value) const { 17407 void Type::set_type_class(const Class& value) const {
17072 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); 17408 ASSERT(!value.IsNull());
17073 StorePointer(&raw_ptr()->type_class_, value.raw()); 17409 StorePointer(&raw_ptr()->type_class_id_,
17410 reinterpret_cast<RawObject*>(Smi::New(value.id())));
17074 } 17411 }
17075 17412
17076 17413
17414 void Type::set_unresolved_class(const Object& value) const {
17415 ASSERT(!value.IsNull() && value.IsUnresolvedClass());
17416 StorePointer(&raw_ptr()->type_class_id_, value.raw());
17417 }
17418
17419
17077 void Type::set_arguments(const TypeArguments& value) const { 17420 void Type::set_arguments(const TypeArguments& value) const {
17078 ASSERT(!IsCanonical()); 17421 ASSERT(!IsCanonical());
17079 StorePointer(&raw_ptr()->arguments_, value.raw()); 17422 StorePointer(&raw_ptr()->arguments_, value.raw());
17080 } 17423 }
17081 17424
17082 17425
17083 RawType* Type::New(Heap::Space space) { 17426 RawType* Type::New(Heap::Space space) {
17084 RawObject* raw = Object::Allocate(Type::kClassId, 17427 RawObject* raw = Object::Allocate(Type::kClassId,
17085 Type::InstanceSize(), 17428 Type::InstanceSize(),
17086 space); 17429 space);
17087 return reinterpret_cast<RawType*>(raw); 17430 return reinterpret_cast<RawType*>(raw);
17088 } 17431 }
17089 17432
17090 17433
17091 RawType* Type::New(const Object& clazz, 17434 RawType* Type::New(const Object& clazz,
17092 const TypeArguments& arguments, 17435 const TypeArguments& arguments,
17093 TokenPosition token_pos, 17436 TokenPosition token_pos,
17094 Heap::Space space) { 17437 Heap::Space space) {
17095 const Type& result = Type::Handle(Type::New(space)); 17438 const Type& result = Type::Handle(Type::New(space));
17096 result.set_type_class(clazz); 17439 if (clazz.IsClass()) {
17440 result.set_type_class(Class::Cast(clazz));
17441 } else {
17442 result.set_unresolved_class(clazz);
17443 }
17097 result.set_arguments(arguments); 17444 result.set_arguments(arguments);
17098 result.set_token_pos(token_pos); 17445 result.set_token_pos(token_pos);
17099 result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated); 17446 result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated);
17100 return result.raw(); 17447 return result.raw();
17101 } 17448 }
17102 17449
17103 17450
17104 void Type::set_token_pos(TokenPosition token_pos) const { 17451 void Type::set_token_pos(TokenPosition token_pos) const {
17105 ASSERT(!token_pos.IsClassifying()); 17452 ASSERT(!token_pos.IsClassifying());
17106 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); 17453 StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
17334 } 17681 }
17335 if (IsFinalized() == other_type_param.IsFinalized()) { 17682 if (IsFinalized() == other_type_param.IsFinalized()) {
17336 return index() == other_type_param.index(); 17683 return index() == other_type_param.index();
17337 } 17684 }
17338 return name() == other_type_param.name(); 17685 return name() == other_type_param.name();
17339 } 17686 }
17340 17687
17341 17688
17342 void TypeParameter::set_parameterized_class(const Class& value) const { 17689 void TypeParameter::set_parameterized_class(const Class& value) const {
17343 // Set value may be null. 17690 // Set value may be null.
17344 StorePointer(&raw_ptr()->parameterized_class_, value.raw()); 17691 classid_t cid = kIllegalCid;
17692 if (!value.IsNull()) {
17693 cid = value.id();
17694 }
17695 StoreNonPointer(&raw_ptr()->parameterized_class_id_, cid);
17345 } 17696 }
17346 17697
17347 17698
17699 classid_t TypeParameter::parameterized_class_id() const {
17700 return raw_ptr()->parameterized_class_id_;
17701 }
17702
17703
17704 RawClass* TypeParameter::parameterized_class() const {
17705 classid_t cid = parameterized_class_id();
17706 if (cid == kIllegalCid) {
17707 return Class::null();
17708 }
17709 return Isolate::Current()->class_table()->At(cid);
17710 }
17711
17712
17348 void TypeParameter::set_index(intptr_t value) const { 17713 void TypeParameter::set_index(intptr_t value) const {
17349 ASSERT(value >= 0); 17714 ASSERT(value >= 0);
17350 ASSERT(Utils::IsInt(16, value)); 17715 ASSERT(Utils::IsInt(16, value));
17351 StoreNonPointer(&raw_ptr()->index_, value); 17716 StoreNonPointer(&raw_ptr()->index_, value);
17352 } 17717 }
17353 17718
17354 17719
17355 void TypeParameter::set_name(const String& value) const { 17720 void TypeParameter::set_name(const String& value) const {
17356 ASSERT(value.IsSymbol()); 17721 ASSERT(value.IsSymbol());
17357 StorePointer(&raw_ptr()->name_, value.raw()); 17722 StorePointer(&raw_ptr()->name_, value.raw());
(...skipping 5099 matching lines...) Expand 10 before | Expand all | Expand 10 after
22457 return UserTag::null(); 22822 return UserTag::null();
22458 } 22823 }
22459 22824
22460 22825
22461 const char* UserTag::ToCString() const { 22826 const char* UserTag::ToCString() const {
22462 const String& tag_label = String::Handle(label()); 22827 const String& tag_label = String::Handle(label());
22463 return tag_label.ToCString(); 22828 return tag_label.ToCString();
22464 } 22829 }
22465 22830
22466 } // namespace dart 22831 } // namespace dart
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | runtime/vm/object_reload.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698