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

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 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
8917 void Script::set_source(const String& value) const { 9010 void Script::set_source(const String& value) const {
8918 StorePointer(&raw_ptr()->source_, value.raw()); 9011 StorePointer(&raw_ptr()->source_, value.raw());
8919 } 9012 }
8920 9013
8921 9014
8922 void Script::set_kind(RawScript::Kind value) const { 9015 void Script::set_kind(RawScript::Kind value) const {
8923 StoreNonPointer(&raw_ptr()->kind_, value); 9016 StoreNonPointer(&raw_ptr()->kind_, value);
8924 } 9017 }
8925 9018
8926 9019
9020 void Script::set_load_timestamp(int64_t value) const {
9021 StoreNonPointer(&raw_ptr()->load_timestamp_, value);
9022 }
9023
9024
8927 void Script::set_tokens(const TokenStream& value) const { 9025 void Script::set_tokens(const TokenStream& value) const {
8928 StorePointer(&raw_ptr()->tokens_, value.raw()); 9026 StorePointer(&raw_ptr()->tokens_, value.raw());
8929 } 9027 }
8930 9028
8931 9029
8932 void Script::Tokenize(const String& private_key, 9030 void Script::Tokenize(const String& private_key,
8933 bool use_shared_tokens) const { 9031 bool use_shared_tokens) const {
8934 Thread* thread = Thread::Current(); 9032 Thread* thread = Thread::Current();
8935 Zone* zone = thread->zone(); 9033 Zone* zone = thread->zone();
8936 const TokenStream& tkns = TokenStream::Handle(zone, tokens()); 9034 const TokenStream& tkns = TokenStream::Handle(zone, tokens());
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
9172 9270
9173 RawScript* Script::New(const String& url, 9271 RawScript* Script::New(const String& url,
9174 const String& source, 9272 const String& source,
9175 RawScript::Kind kind) { 9273 RawScript::Kind kind) {
9176 Thread* thread = Thread::Current(); 9274 Thread* thread = Thread::Current();
9177 Zone* zone = thread->zone(); 9275 Zone* zone = thread->zone();
9178 const Script& result = Script::Handle(zone, Script::New()); 9276 const Script& result = Script::Handle(zone, Script::New());
9179 result.set_url(String::Handle(zone, Symbols::New(thread, url))); 9277 result.set_url(String::Handle(zone, Symbols::New(thread, url)));
9180 result.set_source(source); 9278 result.set_source(source);
9181 result.set_kind(kind); 9279 result.set_kind(kind);
9280 result.set_load_timestamp(FLAG_remove_script_timestamps_for_test
9281 ? 0 : OS::GetCurrentTimeMillis());
9182 result.SetLocationOffset(0, 0); 9282 result.SetLocationOffset(0, 0);
9183 return result.raw(); 9283 return result.raw();
9184 } 9284 }
9185 9285
9186 9286
9187 const char* Script::ToCString() const { 9287 const char* Script::ToCString() const {
9188 return "Script"; 9288 const String& name = String::Handle(url());
9289 return OS::SCreate(Thread::Current()->zone(), "Script(%s)", name.ToCString());
9189 } 9290 }
9190 9291
9191 9292
9192 RawLibrary* Script::FindLibrary() const { 9293 RawLibrary* Script::FindLibrary() const {
9193 Thread* thread = Thread::Current(); 9294 Thread* thread = Thread::Current();
9194 Zone* zone = thread->zone(); 9295 Zone* zone = thread->zone();
9195 Isolate* isolate = thread->isolate(); 9296 Isolate* isolate = thread->isolate();
9196 const GrowableObjectArray& libs = GrowableObjectArray::Handle(zone, 9297 const GrowableObjectArray& libs = GrowableObjectArray::Handle(zone,
9197 isolate->object_store()->libraries()); 9298 isolate->object_store()->libraries());
9198 Library& lib = Library::Handle(zone); 9299 Library& lib = Library::Handle(zone);
(...skipping 3466 matching lines...) Expand 10 before | Expand all | Expand 10 after
12665 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) { 12766 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) {
12666 return num_args + 1 /* target function*/ + 1 /* frequency */; 12767 return num_args + 1 /* target function*/ + 1 /* frequency */;
12667 } 12768 }
12668 12769
12669 12770
12670 intptr_t ICData::TestEntryLength() const { 12771 intptr_t ICData::TestEntryLength() const {
12671 return TestEntryLengthFor(NumArgsTested()); 12772 return TestEntryLengthFor(NumArgsTested());
12672 } 12773 }
12673 12774
12674 12775
12776 intptr_t ICData::Length() const {
12777 return (Smi::Value(ic_data()->ptr()->length_) / TestEntryLength());
12778 }
12779
12780
12675 intptr_t ICData::NumberOfChecks() const { 12781 intptr_t ICData::NumberOfChecks() const {
12676 // Do not count the sentinel; 12782 const intptr_t length = Length();
12677 return (Smi::Value(ic_data()->ptr()->length_) / TestEntryLength()) - 1; 12783 for (intptr_t i = 0; i < length; i++) {
12784 if (IsSentinelAt(i)) {
12785 return i;
12786 }
12787 }
12788 UNREACHABLE();
12789 return -1;
12678 } 12790 }
12679 12791
12680 12792
12681 // Discounts any checks with usage of zero. 12793 // Discounts any checks with usage of zero.
12682 intptr_t ICData::NumberOfUsedChecks() const { 12794 intptr_t ICData::NumberOfUsedChecks() const {
12683 intptr_t n = NumberOfChecks(); 12795 intptr_t n = NumberOfChecks();
12684 if (n == 0) { 12796 if (n == 0) {
12685 return 0; 12797 return 0;
12686 } 12798 }
12687 intptr_t count = 0; 12799 intptr_t count = 0;
(...skipping 16 matching lines...) Expand all
12704 12816
12705 #if defined(DEBUG) 12817 #if defined(DEBUG)
12706 // Used in asserts to verify that a check is not added twice. 12818 // Used in asserts to verify that a check is not added twice.
12707 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { 12819 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const {
12708 const intptr_t len = NumberOfChecks(); 12820 const intptr_t len = NumberOfChecks();
12709 for (intptr_t i = 0; i < len; i++) { 12821 for (intptr_t i = 0; i < len; i++) {
12710 GrowableArray<intptr_t> class_ids; 12822 GrowableArray<intptr_t> class_ids;
12711 GetClassIdsAt(i, &class_ids); 12823 GetClassIdsAt(i, &class_ids);
12712 bool matches = true; 12824 bool matches = true;
12713 for (intptr_t k = 0; k < class_ids.length(); k++) { 12825 for (intptr_t k = 0; k < class_ids.length(); k++) {
12826 ASSERT(class_ids[k] != kIllegalCid);
12714 if (class_ids[k] != cids[k]) { 12827 if (class_ids[k] != cids[k]) {
12715 matches = false; 12828 matches = false;
12716 break; 12829 break;
12717 } 12830 }
12718 } 12831 }
12719 if (matches) { 12832 if (matches) {
12720 return true; 12833 return true;
12721 } 12834 }
12722 } 12835 }
12723 return false; 12836 return false;
12724 } 12837 }
12725 #endif // DEBUG 12838 #endif // DEBUG
12726 12839
12727 12840
12841 void ICData::WriteSentinelAt(intptr_t index) const {
12842 const intptr_t len = Length();
12843 ASSERT(index >= 0);
12844 ASSERT(index < len);
12845 Array& data = Array::Handle(ic_data());
12846 const intptr_t start = index * TestEntryLength();
12847 const intptr_t end = start + TestEntryLength();
12848 for (intptr_t i = start; i < end; i++) {
12849 data.SetAt(i, smi_illegal_cid());
12850 }
12851 }
12852
12853
12854 void ICData::ClearCountAt(intptr_t index) const {
12855 const intptr_t len = NumberOfChecks();
12856 ASSERT(index >= 0);
12857 ASSERT(index < len);
12858 SetCountAt(index, 0);
12859 }
12860
12861
12862 void ICData::ClearWithSentinel() const {
12863 if (IsImmutable()) {
12864 return;
12865 }
12866 // Write the sentinel value into all entries except the first one.
12867 const intptr_t len = Length();
12868 if (len == 0) {
12869 return;
12870 }
12871 // The final entry is always the sentinel.
12872 ASSERT(IsSentinelAt(len - 1));
12873 for (intptr_t i = len - 1; i > 0; i--) {
12874 WriteSentinelAt(i);
12875 }
12876 if (NumArgsTested() != 2) {
12877 // Not the smi fast path case, write sentinel to first one and exit.
12878 WriteSentinelAt(0);
12879 return;
12880 }
12881 if (IsSentinelAt(0)) {
12882 return;
12883 }
12884 Zone* zone = Thread::Current()->zone();
12885 const String& name = String::Handle(target_name());
12886 const Class& smi_class = Class::Handle(Smi::Class());
12887 const Function& smi_op_target =
12888 Function::Handle(Resolver::ResolveDynamicAnyArgs(zone, smi_class, name));
12889 GrowableArray<intptr_t> class_ids(2);
12890 Function& target = Function::Handle();
12891 GetCheckAt(0, &class_ids, &target);
12892 if ((target.raw() == smi_op_target.raw()) &&
12893 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
12894 // The smi fast path case, preserve the initial entry but reset the count.
12895 ClearCountAt(0);
12896 return;
12897 }
12898 WriteSentinelAt(0);
12899 }
12900
12901
12902 void ICData::ClearAndSetStaticTarget(const Function& func) const {
12903 if (IsImmutable()) {
12904 return;
12905 }
12906 const intptr_t len = Length();
12907 if (len == 0) {
12908 return;
12909 }
12910 // The final entry is always the sentinel.
12911 ASSERT(IsSentinelAt(len - 1));
12912 if (NumArgsTested() == 0) {
12913 // No type feedback is being collected.
12914 const Array& data = Array::Handle(ic_data());
12915 // Static calls with no argument checks hold only one target and the
12916 // sentinel value.
12917 ASSERT(len == 2);
12918 // Static calls with no argument checks only need two words.
12919 ASSERT(TestEntryLength() == 2);
12920 // Set the target.
12921 data.SetAt(0, func);
12922 // Set count to 0 as this is called during compilation, before the
12923 // call has been executed.
12924 const Smi& value = Smi::Handle(Smi::New(0));
12925 data.SetAt(1, value);
12926 } else {
12927 // Type feedback on arguments is being collected.
12928 const Array& data = Array::Handle(ic_data());
12929
12930 // Fill all but the first entry with the sentinel.
12931 for (intptr_t i = len - 1; i > 0; i--) {
12932 WriteSentinelAt(i);
12933 }
12934 // Rewrite the dummy entry.
12935 const Smi& object_cid = Smi::Handle(Smi::New(kObjectCid));
12936 for (intptr_t i = 0; i < NumArgsTested(); i++) {
12937 data.SetAt(i, object_cid);
12938 }
12939 data.SetAt(NumArgsTested(), func);
12940 const Smi& value = Smi::Handle(Smi::New(0));
12941 data.SetAt(NumArgsTested() + 1, value);
12942 }
12943 }
12944
12945
12946 // Add an initial Smi/Smi check with count 0.
12947 bool ICData::AddSmiSmiCheckForFastSmiStubs() const {
12948 bool is_smi_two_args_op = false;
12949
12950 ASSERT(NumArgsTested() == 2);
12951 const String& name = String::Handle(target_name());
12952 const Class& smi_class = Class::Handle(Smi::Class());
12953 Zone* zone = Thread::Current()->zone();
12954 const Function& smi_op_target =
12955 Function::Handle(Resolver::ResolveDynamicAnyArgs(zone, smi_class, name));
12956 if (NumberOfChecks() == 0) {
12957 GrowableArray<intptr_t> class_ids(2);
12958 class_ids.Add(kSmiCid);
12959 class_ids.Add(kSmiCid);
12960 AddCheck(class_ids, smi_op_target);
12961 // 'AddCheck' sets the initial count to 1.
12962 SetCountAt(0, 0);
12963 is_smi_two_args_op = true;
12964 } else if (NumberOfChecks() == 1) {
12965 GrowableArray<intptr_t> class_ids(2);
12966 Function& target = Function::Handle();
12967 GetCheckAt(0, &class_ids, &target);
12968 if ((target.raw() == smi_op_target.raw()) &&
12969 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
12970 is_smi_two_args_op = true;
12971 }
12972 }
12973 return is_smi_two_args_op;
12974 }
12975
12976
12728 // Used for unoptimized static calls when no class-ids are checked. 12977 // Used for unoptimized static calls when no class-ids are checked.
12729 void ICData::AddTarget(const Function& target) const { 12978 void ICData::AddTarget(const Function& target) const {
12730 ASSERT(!target.IsNull()); 12979 ASSERT(!target.IsNull());
12731 if (NumArgsTested() > 0) { 12980 if (NumArgsTested() > 0) {
12732 // Create a fake cid entry, so that we can store the target. 12981 // Create a fake cid entry, so that we can store the target.
12733 if (NumArgsTested() == 1) { 12982 if (NumArgsTested() == 1) {
12734 AddReceiverCheck(kObjectCid, target, 1); 12983 AddReceiverCheck(kObjectCid, target, 1);
12735 } else { 12984 } else {
12736 GrowableArray<intptr_t> class_ids(NumArgsTested()); 12985 GrowableArray<intptr_t> class_ids(NumArgsTested());
12737 for (intptr_t i = 0; i < NumArgsTested(); i++) { 12986 for (intptr_t i = 0; i < NumArgsTested(); i++) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
12787 // Replace dummy entry. 13036 // Replace dummy entry.
12788 Smi& value = Smi::Handle(); 13037 Smi& value = Smi::Handle();
12789 for (intptr_t i = 0; i < NumArgsTested(); i++) { 13038 for (intptr_t i = 0; i < NumArgsTested(); i++) {
12790 ASSERT(class_ids[i] != kIllegalCid); 13039 ASSERT(class_ids[i] != kIllegalCid);
12791 value = Smi::New(class_ids[i]); 13040 value = Smi::New(class_ids[i]);
12792 data.SetAt(i, value); 13041 data.SetAt(i, value);
12793 } 13042 }
12794 return; 13043 return;
12795 } 13044 }
12796 } 13045 }
12797 const intptr_t new_len = data.Length() + TestEntryLength(); 13046 intptr_t index = -1;
12798 data = Array::Grow(data, new_len, Heap::kOld); 13047 data = FindFreeIndex(&index);
12799 WriteSentinel(data, TestEntryLength()); 13048 ASSERT(!data.IsNull());
12800 intptr_t data_pos = old_num * TestEntryLength(); 13049 intptr_t data_pos = index * TestEntryLength();
12801 Smi& value = Smi::Handle(); 13050 Smi& value = Smi::Handle();
12802 for (intptr_t i = 0; i < class_ids.length(); i++) { 13051 for (intptr_t i = 0; i < class_ids.length(); i++) {
12803 // kIllegalCid is used as terminating value, do not add it. 13052 // kIllegalCid is used as terminating value, do not add it.
12804 ASSERT(class_ids[i] != kIllegalCid); 13053 ASSERT(class_ids[i] != kIllegalCid);
12805 value = Smi::New(class_ids[i]); 13054 value = Smi::New(class_ids[i]);
12806 data.SetAt(data_pos++, value); 13055 data.SetAt(data_pos++, value);
12807 } 13056 }
12808 ASSERT(!target.IsNull()); 13057 ASSERT(!target.IsNull());
12809 data.SetAt(data_pos++, target); 13058 data.SetAt(data_pos++, target);
12810 value = Smi::New(1); 13059 value = Smi::New(1);
12811 data.SetAt(data_pos, value); 13060 data.SetAt(data_pos, value);
12812 // Multithreaded access to ICData requires setting of array to be the last 13061 // Multithreaded access to ICData requires setting of array to be the last
12813 // operation. 13062 // operation.
12814 set_ic_data_array(data); 13063 set_ic_data_array(data);
12815 } 13064 }
12816 13065
12817 13066
13067 RawArray* ICData::FindFreeIndex(intptr_t* index) const {
13068 // The final entry is always the sentinel value, don't consider it
13069 // when searching.
13070 const intptr_t len = Length() - 1;
13071 Array& data = Array::Handle(ic_data());
13072 *index = len;
13073 for (intptr_t i = 0; i < len; i++) {
13074 if (IsSentinelAt(i)) {
13075 *index = i;
13076 break;
13077 }
13078 }
13079 if (*index < len) {
13080 // We've found a free slot.
13081 return data.raw();
13082 }
13083 // Append case.
13084 ASSERT(*index == len);
13085 ASSERT(*index >= 0);
13086 // Grow array.
13087 const intptr_t new_len = data.Length() + TestEntryLength();
13088 data = Array::Grow(data, new_len, Heap::kOld);
13089 WriteSentinel(data, TestEntryLength());
13090 return data.raw();
13091 }
13092
13093
13094 void ICData::DebugDump() const {
13095 const Function& owner = Function::Handle(Owner());
13096 THR_Print("ICData::DebugDump\n");
13097 THR_Print("Owner = %s [deopt=%" Pd "]\n", owner.ToCString(), deopt_id());
13098 THR_Print("NumArgsTested = %" Pd "\n", NumArgsTested());
13099 THR_Print("Length = %" Pd "\n", Length());
13100 THR_Print("NumberOfChecks = %" Pd "\n", NumberOfChecks());
13101
13102 GrowableArray<intptr_t> class_ids;
13103 for (intptr_t i = 0; i < NumberOfChecks(); i++) {
13104 THR_Print("Check[%" Pd "]:", i);
13105 GetClassIdsAt(i, &class_ids);
13106 for (intptr_t c = 0; c < class_ids.length(); c++) {
13107 THR_Print(" %" Pd "", class_ids[c]);
13108 }
13109 THR_Print("--- %" Pd " hits\n", GetCountAt(i));
13110 }
13111 }
13112
13113
13114 void ICData::ValidateSentinelLocations() const {
13115 }
13116
13117
12818 void ICData::AddReceiverCheck(intptr_t receiver_class_id, 13118 void ICData::AddReceiverCheck(intptr_t receiver_class_id,
12819 const Function& target, 13119 const Function& target,
12820 intptr_t count) const { 13120 intptr_t count) const {
12821 #if defined(DEBUG) 13121 #if defined(DEBUG)
12822 GrowableArray<intptr_t> class_ids(1); 13122 GrowableArray<intptr_t> class_ids(1);
12823 class_ids.Add(receiver_class_id); 13123 class_ids.Add(receiver_class_id);
12824 ASSERT(!HasCheck(class_ids)); 13124 ASSERT(!HasCheck(class_ids));
12825 #endif // DEBUG 13125 #endif // DEBUG
12826 ASSERT(!target.IsNull()); 13126 ASSERT(!target.IsNull());
12827 ASSERT(NumArgsTested() == 1); // Otherwise use 'AddCheck'. 13127 ASSERT(NumArgsTested() == 1); // Otherwise use 'AddCheck'.
12828 ASSERT(receiver_class_id != kIllegalCid); 13128 ASSERT(receiver_class_id != kIllegalCid);
12829 13129
12830 const intptr_t old_num = NumberOfChecks(); 13130 intptr_t index = -1;
12831 Array& data = Array::Handle(ic_data()); 13131 Array& data = Array::Handle(FindFreeIndex(&index));
12832 const intptr_t new_len = data.Length() + TestEntryLength(); 13132 intptr_t data_pos = index * TestEntryLength();
12833 data = Array::Grow(data, new_len, Heap::kOld);
12834 WriteSentinel(data, TestEntryLength());
12835 intptr_t data_pos = old_num * TestEntryLength();
12836 if ((receiver_class_id == kSmiCid) && (data_pos > 0)) { 13133 if ((receiver_class_id == kSmiCid) && (data_pos > 0)) {
12837 ASSERT(GetReceiverClassIdAt(0) != kSmiCid); 13134 ASSERT(GetReceiverClassIdAt(0) != kSmiCid);
12838 // Move class occupying position 0 to the data_pos. 13135 // Move class occupying position 0 to the data_pos.
12839 for (intptr_t i = 0; i < TestEntryLength(); i++) { 13136 for (intptr_t i = 0; i < TestEntryLength(); i++) {
12840 data.SetAt(data_pos + i, Object::Handle(data.At(i))); 13137 data.SetAt(data_pos + i, Object::Handle(data.At(i)));
12841 } 13138 }
12842 // Insert kSmiCid in position 0. 13139 // Insert kSmiCid in position 0.
12843 data_pos = 0; 13140 data_pos = 0;
12844 } 13141 }
12845 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); 13142 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id)));
(...skipping 24 matching lines...) Expand all
12870 class_ids->Clear(); 13167 class_ids->Clear();
12871 const Array& data = Array::Handle(ic_data()); 13168 const Array& data = Array::Handle(ic_data());
12872 intptr_t data_pos = index * TestEntryLength(); 13169 intptr_t data_pos = index * TestEntryLength();
12873 for (intptr_t i = 0; i < NumArgsTested(); i++) { 13170 for (intptr_t i = 0; i < NumArgsTested(); i++) {
12874 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); 13171 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
12875 } 13172 }
12876 (*target) ^= data.At(data_pos++); 13173 (*target) ^= data.At(data_pos++);
12877 } 13174 }
12878 13175
12879 13176
13177 bool ICData::IsSentinelAt(intptr_t index) const {
13178 ASSERT(index < Length());
13179 const Array& data = Array::Handle(ic_data());
13180 const intptr_t entry_length = TestEntryLength();
13181 intptr_t data_pos = index * TestEntryLength();
13182 for (intptr_t i = 0; i < entry_length; i++) {
13183 if (data.At(data_pos++) != smi_illegal_cid().raw()) {
13184 return false;
13185 }
13186 }
13187 // The entry at |index| was filled with the value kIllegalCid.
13188 return true;
13189 }
13190
13191
12880 void ICData::GetClassIdsAt(intptr_t index, 13192 void ICData::GetClassIdsAt(intptr_t index,
12881 GrowableArray<intptr_t>* class_ids) const { 13193 GrowableArray<intptr_t>* class_ids) const {
12882 ASSERT(index < NumberOfChecks()); 13194 ASSERT(index < Length());
12883 ASSERT(class_ids != NULL); 13195 ASSERT(class_ids != NULL);
13196 ASSERT(!IsSentinelAt(index));
12884 class_ids->Clear(); 13197 class_ids->Clear();
12885 const Array& data = Array::Handle(ic_data()); 13198 const Array& data = Array::Handle(ic_data());
12886 intptr_t data_pos = index * TestEntryLength(); 13199 intptr_t data_pos = index * TestEntryLength();
12887 for (intptr_t i = 0; i < NumArgsTested(); i++) { 13200 for (intptr_t i = 0; i < NumArgsTested(); i++) {
12888 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); 13201 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
12889 } 13202 }
12890 } 13203 }
12891 13204
12892 13205
12893 void ICData::GetOneClassCheckAt(intptr_t index, 13206 void ICData::GetOneClassCheckAt(intptr_t index,
(...skipping 18 matching lines...) Expand all
12912 13225
12913 13226
12914 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const { 13227 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const {
12915 GrowableArray<intptr_t> class_ids; 13228 GrowableArray<intptr_t> class_ids;
12916 GetClassIdsAt(index, &class_ids); 13229 GetClassIdsAt(index, &class_ids);
12917 return class_ids[arg_nr]; 13230 return class_ids[arg_nr];
12918 } 13231 }
12919 13232
12920 13233
12921 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const { 13234 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const {
12922 ASSERT(index < NumberOfChecks()); 13235 ASSERT(index < Length());
13236 ASSERT(!IsSentinelAt(index));
12923 const intptr_t data_pos = index * TestEntryLength(); 13237 const intptr_t data_pos = index * TestEntryLength();
12924 NoSafepointScope no_safepoint; 13238 NoSafepointScope no_safepoint;
12925 RawArray* raw_data = ic_data(); 13239 RawArray* raw_data = ic_data();
12926 return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos])); 13240 return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos]));
12927 } 13241 }
12928 13242
12929 13243
12930 RawFunction* ICData::GetTargetAt(intptr_t index) const { 13244 RawFunction* ICData::GetTargetAt(intptr_t index) const {
12931 ASSERT(Isolate::Current()->compilation_allowed()); 13245 ASSERT(Isolate::Current()->compilation_allowed());
12932 const intptr_t data_pos = index * TestEntryLength() + NumArgsTested(); 13246 const intptr_t data_pos = index * TestEntryLength() + NumArgsTested();
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
13116 &Function::ZoneHandle(GetTargetAt(i)))); 13430 &Function::ZoneHandle(GetTargetAt(i))));
13117 } 13431 }
13118 } 13432 }
13119 aggregate.Sort(CidCount::HighestCountFirst); 13433 aggregate.Sort(CidCount::HighestCountFirst);
13120 13434
13121 ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested)); 13435 ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested));
13122 ASSERT(result.NumberOfChecks() == 0); 13436 ASSERT(result.NumberOfChecks() == 0);
13123 // Room for all entries and the sentinel. 13437 // Room for all entries and the sentinel.
13124 const intptr_t data_len = 13438 const intptr_t data_len =
13125 result.TestEntryLength() * (aggregate.length() + 1); 13439 result.TestEntryLength() * (aggregate.length() + 1);
13440 // Allocate the array but do not assign it to result until we have populated
13441 // it with the aggregate data and the terminating sentinel.
13126 const Array& data = Array::Handle(Array::New(data_len, Heap::kOld)); 13442 const Array& data = Array::Handle(Array::New(data_len, Heap::kOld));
13127 result.set_ic_data_array(data);
13128 ASSERT(result.NumberOfChecks() == aggregate.length());
13129
13130 intptr_t pos = 0; 13443 intptr_t pos = 0;
13131 for (intptr_t i = 0; i < aggregate.length(); i++) { 13444 for (intptr_t i = 0; i < aggregate.length(); i++) {
13132 data.SetAt(pos + 0, Smi::Handle(Smi::New(aggregate[i].cid))); 13445 data.SetAt(pos + 0, Smi::Handle(Smi::New(aggregate[i].cid)));
13133 data.SetAt(pos + TargetIndexFor(1), *aggregate[i].function); 13446 data.SetAt(pos + TargetIndexFor(1), *aggregate[i].function);
13134 data.SetAt(pos + CountIndexFor(1), 13447 data.SetAt(pos + CountIndexFor(1),
13135 Smi::Handle(Smi::New(aggregate[i].count))); 13448 Smi::Handle(Smi::New(aggregate[i].count)));
13136 13449
13137 pos += result.TestEntryLength(); 13450 pos += result.TestEntryLength();
13138 } 13451 }
13139 WriteSentinel(data, result.TestEntryLength()); 13452 WriteSentinel(data, result.TestEntryLength());
13140 result.set_ic_data_array(data); 13453 result.set_ic_data_array(data);
13454 ASSERT(result.NumberOfChecks() == aggregate.length());
13141 return result.raw(); 13455 return result.raw();
13142 } 13456 }
13143 13457
13144 13458
13145 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const { 13459 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const {
13146 if (NumberOfChecks() == 0) return false; 13460 if (NumberOfChecks() == 0) return false;
13147 Class& cls = Class::Handle(); 13461 Class& cls = Class::Handle();
13148 const intptr_t len = NumberOfChecks(); 13462 const intptr_t len = NumberOfChecks();
13149 for (intptr_t i = 0; i < len; i++) { 13463 for (intptr_t i = 0; i < len; i++) {
13150 if (IsUsedAt(i)) { 13464 if (IsUsedAt(i)) {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
13277 result.set_deopt_id(deopt_id); 13591 result.set_deopt_id(deopt_id);
13278 result.set_state_bits(0); 13592 result.set_state_bits(0);
13279 #if defined(TAG_IC_DATA) 13593 #if defined(TAG_IC_DATA)
13280 result.set_tag(-1); 13594 result.set_tag(-1);
13281 #endif 13595 #endif
13282 result.SetNumArgsTested(num_args_tested); 13596 result.SetNumArgsTested(num_args_tested);
13283 return result.raw(); 13597 return result.raw();
13284 } 13598 }
13285 13599
13286 13600
13601 bool ICData::IsImmutable() const {
13602 const Array& data = Array::Handle(ic_data());
13603 return data.IsImmutable();
13604 }
13605
13606
13607 void ICData::ResetData() const {
13608 // Number of array elements in one test entry.
13609 intptr_t len = TestEntryLength();
13610 // IC data array must be null terminated (sentinel entry).
13611 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld));
13612 set_ic_data_array(ic_data);
13613 WriteSentinel(ic_data, len);
13614 }
13615
13616
13287 RawICData* ICData::New() { 13617 RawICData* ICData::New() {
13288 ICData& result = ICData::Handle(); 13618 ICData& result = ICData::Handle();
13289 { 13619 {
13290 // IC data objects are long living objects, allocate them in old generation. 13620 // IC data objects are long living objects, allocate them in old generation.
13291 RawObject* raw = Object::Allocate(ICData::kClassId, 13621 RawObject* raw = Object::Allocate(ICData::kClassId,
13292 ICData::InstanceSize(), 13622 ICData::InstanceSize(),
13293 Heap::kOld); 13623 Heap::kOld);
13294 NoSafepointScope no_safepoint; 13624 NoSafepointScope no_safepoint;
13295 result ^= raw; 13625 result ^= raw;
13296 } 13626 }
(...skipping 2302 matching lines...) Expand 10 before | Expand all | Expand 10 after
15599 } 15929 }
15600 15930
15601 15931
15602 bool AbstractType::HasResolvedTypeClass() const { 15932 bool AbstractType::HasResolvedTypeClass() const {
15603 // AbstractType is an abstract class. 15933 // AbstractType is an abstract class.
15604 UNREACHABLE(); 15934 UNREACHABLE();
15605 return false; 15935 return false;
15606 } 15936 }
15607 15937
15608 15938
15939 classid_t AbstractType::type_class_id() const {
15940 // AbstractType is an abstract class.
15941 UNREACHABLE();
15942 return kIllegalCid;
15943 }
15944
15945
15609 RawClass* AbstractType::type_class() const { 15946 RawClass* AbstractType::type_class() const {
15610 // AbstractType is an abstract class. 15947 // AbstractType is an abstract class.
15611 UNREACHABLE(); 15948 UNREACHABLE();
15612 return Class::null(); 15949 return Class::null();
15613 } 15950 }
15614 15951
15615 15952
15616 RawUnresolvedClass* AbstractType::unresolved_class() const { 15953 RawUnresolvedClass* AbstractType::unresolved_class() const {
15617 // AbstractType is an abstract class. 15954 // AbstractType is an abstract class.
15618 UNREACHABLE(); 15955 UNREACHABLE();
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
16464 } 16801 }
16465 16802
16466 16803
16467 void Type::SetIsResolved() const { 16804 void Type::SetIsResolved() const {
16468 ASSERT(!IsResolved()); 16805 ASSERT(!IsResolved());
16469 set_type_state(RawType::kResolved); 16806 set_type_state(RawType::kResolved);
16470 } 16807 }
16471 16808
16472 16809
16473 bool Type::HasResolvedTypeClass() const { 16810 bool Type::HasResolvedTypeClass() const {
16474 return (raw_ptr()->type_class_->GetClassId() == kClassCid); 16811 return !raw_ptr()->type_class_id_->IsHeapObject();
16812 }
16813
16814
16815 classid_t Type::type_class_id() const {
16816 ASSERT(HasResolvedTypeClass());
16817 return Smi::Value(reinterpret_cast<RawSmi*>(raw_ptr()->type_class_id_));
16475 } 16818 }
16476 16819
16477 16820
16478 RawClass* Type::type_class() const { 16821 RawClass* Type::type_class() const {
16479 #ifdef DEBUG 16822 return Isolate::Current()->class_table()->At(type_class_id());
16480 ASSERT(HasResolvedTypeClass());
16481 Class& type_class = Class::Handle();
16482 type_class ^= raw_ptr()->type_class_;
16483 return type_class.raw();
16484 #else
16485 return reinterpret_cast<RawClass*>(raw_ptr()->type_class_);
16486 #endif
16487 } 16823 }
16488 16824
16489 16825
16490 RawUnresolvedClass* Type::unresolved_class() const { 16826 RawUnresolvedClass* Type::unresolved_class() const {
16491 #ifdef DEBUG 16827 #ifdef DEBUG
16492 ASSERT(!HasResolvedTypeClass()); 16828 ASSERT(!HasResolvedTypeClass());
16493 UnresolvedClass& unresolved_class = UnresolvedClass::Handle(); 16829 UnresolvedClass& unresolved_class = UnresolvedClass::Handle();
16494 unresolved_class ^= raw_ptr()->type_class_; 16830 unresolved_class ^= raw_ptr()->type_class_id_;
16495 ASSERT(!unresolved_class.IsNull()); 16831 ASSERT(!unresolved_class.IsNull());
16496 return unresolved_class.raw(); 16832 return unresolved_class.raw();
16497 #else 16833 #else
16498 ASSERT(!Object::Handle(raw_ptr()->type_class_).IsNull()); 16834 ASSERT(!Object::Handle(raw_ptr()->type_class_id_).IsNull());
16499 ASSERT(Object::Handle(raw_ptr()->type_class_).IsUnresolvedClass()); 16835 ASSERT(Object::Handle(raw_ptr()->type_class_id_).IsUnresolvedClass());
16500 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); 16836 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_id_);
16501 #endif 16837 #endif
16502 } 16838 }
16503 16839
16504 16840
16505 bool Type::IsInstantiated(TrailPtr trail) const { 16841 bool Type::IsInstantiated(TrailPtr trail) const {
16506 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { 16842 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) {
16507 return true; 16843 return true;
16508 } 16844 }
16509 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { 16845 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) {
16510 return false; 16846 return false;
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
17056 for (intptr_t i = sig_fun.num_fixed_parameters(); i < num_params; i++) { 17392 for (intptr_t i = sig_fun.num_fixed_parameters(); i < num_params; i++) {
17057 param_name = sig_fun.ParameterNameAt(i); 17393 param_name = sig_fun.ParameterNameAt(i);
17058 result = CombineHashes(result, param_name.Hash()); 17394 result = CombineHashes(result, param_name.Hash());
17059 } 17395 }
17060 } 17396 }
17061 } 17397 }
17062 return FinalizeHash(result); 17398 return FinalizeHash(result);
17063 } 17399 }
17064 17400
17065 17401
17066 void Type::set_type_class(const Object& value) const { 17402 void Type::set_type_class(const Class& value) const {
17067 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); 17403 ASSERT(!value.IsNull());
17068 StorePointer(&raw_ptr()->type_class_, value.raw()); 17404 StorePointer(&raw_ptr()->type_class_id_,
17405 reinterpret_cast<RawObject*>(Smi::New(value.id())));
17069 } 17406 }
17070 17407
17071 17408
17409 void Type::set_unresolved_class(const Object& value) const {
17410 ASSERT(!value.IsNull() && value.IsUnresolvedClass());
17411 StorePointer(&raw_ptr()->type_class_id_, value.raw());
17412 }
17413
17414
17072 void Type::set_arguments(const TypeArguments& value) const { 17415 void Type::set_arguments(const TypeArguments& value) const {
17073 ASSERT(!IsCanonical()); 17416 ASSERT(!IsCanonical());
17074 StorePointer(&raw_ptr()->arguments_, value.raw()); 17417 StorePointer(&raw_ptr()->arguments_, value.raw());
17075 } 17418 }
17076 17419
17077 17420
17078 RawType* Type::New(Heap::Space space) { 17421 RawType* Type::New(Heap::Space space) {
17079 RawObject* raw = Object::Allocate(Type::kClassId, 17422 RawObject* raw = Object::Allocate(Type::kClassId,
17080 Type::InstanceSize(), 17423 Type::InstanceSize(),
17081 space); 17424 space);
17082 return reinterpret_cast<RawType*>(raw); 17425 return reinterpret_cast<RawType*>(raw);
17083 } 17426 }
17084 17427
17085 17428
17086 RawType* Type::New(const Object& clazz, 17429 RawType* Type::New(const Object& clazz,
17087 const TypeArguments& arguments, 17430 const TypeArguments& arguments,
17088 TokenPosition token_pos, 17431 TokenPosition token_pos,
17089 Heap::Space space) { 17432 Heap::Space space) {
17090 const Type& result = Type::Handle(Type::New(space)); 17433 const Type& result = Type::Handle(Type::New(space));
17091 result.set_type_class(clazz); 17434 if (clazz.IsClass()) {
17435 result.set_type_class(Class::Cast(clazz));
17436 } else {
17437 result.set_unresolved_class(clazz);
17438 }
17092 result.set_arguments(arguments); 17439 result.set_arguments(arguments);
17093 result.set_token_pos(token_pos); 17440 result.set_token_pos(token_pos);
17094 result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated); 17441 result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated);
17095 return result.raw(); 17442 return result.raw();
17096 } 17443 }
17097 17444
17098 17445
17099 void Type::set_token_pos(TokenPosition token_pos) const { 17446 void Type::set_token_pos(TokenPosition token_pos) const {
17100 ASSERT(!token_pos.IsClassifying()); 17447 ASSERT(!token_pos.IsClassifying());
17101 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); 17448 StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
17329 } 17676 }
17330 if (IsFinalized() == other_type_param.IsFinalized()) { 17677 if (IsFinalized() == other_type_param.IsFinalized()) {
17331 return index() == other_type_param.index(); 17678 return index() == other_type_param.index();
17332 } 17679 }
17333 return name() == other_type_param.name(); 17680 return name() == other_type_param.name();
17334 } 17681 }
17335 17682
17336 17683
17337 void TypeParameter::set_parameterized_class(const Class& value) const { 17684 void TypeParameter::set_parameterized_class(const Class& value) const {
17338 // Set value may be null. 17685 // Set value may be null.
17339 StorePointer(&raw_ptr()->parameterized_class_, value.raw()); 17686 classid_t cid = kIllegalCid;
17687 if (!value.IsNull()) {
17688 cid = value.id();
17689 }
17690 StorePointer(&raw_ptr()->parameterized_class_id_,
17691 reinterpret_cast<RawObject*>(Smi::New(cid)));
17340 } 17692 }
17341 17693
17342 17694
17695 classid_t TypeParameter::parameterized_class_id() const {
17696 return Smi::Value(Smi::RawCast(raw_ptr()->parameterized_class_id_));
17697 }
17698
17699
17700 RawClass* TypeParameter::parameterized_class() const {
17701 classid_t cid = parameterized_class_id();
17702 if (cid == kIllegalCid) {
17703 return Class::null();
17704 }
17705 return Isolate::Current()->class_table()->At(cid);
17706 }
17707
17708
17343 void TypeParameter::set_index(intptr_t value) const { 17709 void TypeParameter::set_index(intptr_t value) const {
17344 ASSERT(value >= 0); 17710 ASSERT(value >= 0);
17345 ASSERT(Utils::IsInt(16, value)); 17711 ASSERT(Utils::IsInt(16, value));
17346 StoreNonPointer(&raw_ptr()->index_, value); 17712 StoreNonPointer(&raw_ptr()->index_, value);
17347 } 17713 }
17348 17714
17349 17715
17350 void TypeParameter::set_name(const String& value) const { 17716 void TypeParameter::set_name(const String& value) const {
17351 ASSERT(value.IsSymbol()); 17717 ASSERT(value.IsSymbol());
17352 StorePointer(&raw_ptr()->name_, value.raw()); 17718 StorePointer(&raw_ptr()->name_, value.raw());
(...skipping 5099 matching lines...) Expand 10 before | Expand all | Expand 10 after
22452 return UserTag::null(); 22818 return UserTag::null();
22453 } 22819 }
22454 22820
22455 22821
22456 const char* UserTag::ToCString() const { 22822 const char* UserTag::ToCString() const {
22457 const String& tag_label = String::Handle(label()); 22823 const String& tag_label = String::Handle(label());
22458 return tag_label.ToCString(); 22824 return tag_label.ToCString();
22459 } 22825 }
22460 22826
22461 } // namespace dart 22827 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698