| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 5364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5375 void PatchClass::set_source_class(const Class& value) const { | 5375 void PatchClass::set_source_class(const Class& value) const { |
| 5376 StorePointer(&raw_ptr()->source_class_, value.raw()); | 5376 StorePointer(&raw_ptr()->source_class_, value.raw()); |
| 5377 } | 5377 } |
| 5378 | 5378 |
| 5379 | 5379 |
| 5380 bool Function::HasBreakpoint() const { | 5380 bool Function::HasBreakpoint() const { |
| 5381 return Isolate::Current()->debugger()->HasBreakpoint(*this); | 5381 return Isolate::Current()->debugger()->HasBreakpoint(*this); |
| 5382 } | 5382 } |
| 5383 | 5383 |
| 5384 | 5384 |
| 5385 void Function::InstallOptimizedCode(const Code& code, bool is_osr) const { |
| 5386 // We may not have previous code if 'always_optimize' is set. |
| 5387 if (!is_osr && HasCode()) { |
| 5388 Code::Handle(CurrentCode()).DisableDartCode(); |
| 5389 } |
| 5390 AttachCode(code); |
| 5391 } |
| 5392 |
| 5393 |
| 5385 void Function::SetInstructions(const Code& value) const { | 5394 void Function::SetInstructions(const Code& value) const { |
| 5395 ASSERT(Thread::Current()->IsMutatorThread()); |
| 5396 SetInstructionsSafe(value); |
| 5397 } |
| 5398 |
| 5399 |
| 5400 void Function::SetInstructionsSafe(const Code& value) const { |
| 5386 StorePointer(&raw_ptr()->code_, value.raw()); | 5401 StorePointer(&raw_ptr()->code_, value.raw()); |
| 5387 StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint()); | 5402 StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint()); |
| 5388 } | 5403 } |
| 5389 | 5404 |
| 5405 |
| 5390 void Function::AttachCode(const Code& value) const { | 5406 void Function::AttachCode(const Code& value) const { |
| 5391 // Finish setting up code before activating it. | 5407 // Finish setting up code before activating it. |
| 5392 value.set_owner(*this); | 5408 value.set_owner(*this); |
| 5393 SetInstructions(value); | 5409 SetInstructions(value); |
| 5394 ASSERT(Function::Handle(value.function()).IsNull() || | 5410 ASSERT(Function::Handle(value.function()).IsNull() || |
| 5395 (value.function() == this->raw())); | 5411 (value.function() == this->raw())); |
| 5396 } | 5412 } |
| 5397 | 5413 |
| 5398 | 5414 |
| 5399 bool Function::HasCode() const { | 5415 bool Function::HasCode() const { |
| (...skipping 1085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6485 result.set_num_fixed_parameters(0); | 6501 result.set_num_fixed_parameters(0); |
| 6486 result.set_num_optional_parameters(0); | 6502 result.set_num_optional_parameters(0); |
| 6487 result.set_usage_counter(0); | 6503 result.set_usage_counter(0); |
| 6488 result.set_deoptimization_counter(0); | 6504 result.set_deoptimization_counter(0); |
| 6489 result.set_optimized_instruction_count(0); | 6505 result.set_optimized_instruction_count(0); |
| 6490 result.set_optimized_call_site_count(0); | 6506 result.set_optimized_call_site_count(0); |
| 6491 result.set_is_optimizable(is_native ? false : true); | 6507 result.set_is_optimizable(is_native ? false : true); |
| 6492 result.set_is_inlinable(true); | 6508 result.set_is_inlinable(true); |
| 6493 result.set_allows_hoisting_check_class(true); | 6509 result.set_allows_hoisting_check_class(true); |
| 6494 result.set_allows_bounds_check_generalization(true); | 6510 result.set_allows_bounds_check_generalization(true); |
| 6495 result.SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); | 6511 result.SetInstructionsSafe( |
| 6512 Code::Handle(StubCode::LazyCompile_entry()->code())); |
| 6496 if (kind == RawFunction::kClosureFunction) { | 6513 if (kind == RawFunction::kClosureFunction) { |
| 6497 const ClosureData& data = ClosureData::Handle(ClosureData::New()); | 6514 const ClosureData& data = ClosureData::Handle(ClosureData::New()); |
| 6498 result.set_data(data); | 6515 result.set_data(data); |
| 6499 } | 6516 } |
| 6500 return result.raw(); | 6517 return result.raw(); |
| 6501 } | 6518 } |
| 6502 | 6519 |
| 6503 | 6520 |
| 6504 RawFunction* Function::Clone(const Class& new_owner) const { | 6521 RawFunction* Function::Clone(const Class& new_owner) const { |
| 6505 ASSERT(!IsGenerativeConstructor()); | 6522 ASSERT(!IsGenerativeConstructor()); |
| (...skipping 5571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12077 ASSERT(!value.IsNull()); | 12094 ASSERT(!value.IsNull()); |
| 12078 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); | 12095 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); |
| 12079 } | 12096 } |
| 12080 | 12097 |
| 12081 void ICData::set_deopt_id(intptr_t value) const { | 12098 void ICData::set_deopt_id(intptr_t value) const { |
| 12082 ASSERT(value <= kMaxInt32); | 12099 ASSERT(value <= kMaxInt32); |
| 12083 StoreNonPointer(&raw_ptr()->deopt_id_, value); | 12100 StoreNonPointer(&raw_ptr()->deopt_id_, value); |
| 12084 } | 12101 } |
| 12085 | 12102 |
| 12086 | 12103 |
| 12087 void ICData::set_ic_data(const Array& value) const { | 12104 void ICData::set_ic_data_array(const Array& value) const { |
| 12088 ASSERT(!value.IsNull()); | 12105 ASSERT(!value.IsNull()); |
| 12089 StorePointer(&raw_ptr()->ic_data_, value.raw()); | 12106 StorePointer(&raw_ptr()->ic_data_, value.raw()); |
| 12090 } | 12107 } |
| 12091 | 12108 |
| 12092 | 12109 |
| 12093 intptr_t ICData::NumArgsTested() const { | 12110 intptr_t ICData::NumArgsTested() const { |
| 12094 return NumArgsTestedBits::decode(raw_ptr()->state_bits_); | 12111 return NumArgsTestedBits::decode(raw_ptr()->state_bits_); |
| 12095 } | 12112 } |
| 12096 | 12113 |
| 12097 | 12114 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12185 intptr_t count = 0; | 12202 intptr_t count = 0; |
| 12186 for (intptr_t i = 0; i < n; i++) { | 12203 for (intptr_t i = 0; i < n; i++) { |
| 12187 if (GetCountAt(i) > 0) { | 12204 if (GetCountAt(i) > 0) { |
| 12188 count++; | 12205 count++; |
| 12189 } | 12206 } |
| 12190 } | 12207 } |
| 12191 return count; | 12208 return count; |
| 12192 } | 12209 } |
| 12193 | 12210 |
| 12194 | 12211 |
| 12195 void ICData::WriteSentinel(const Array& data) const { | 12212 void ICData::WriteSentinel(const Array& data, intptr_t test_entry_length) { |
| 12196 ASSERT(!data.IsNull()); | 12213 ASSERT(!data.IsNull()); |
| 12197 for (intptr_t i = 1; i <= TestEntryLength(); i++) { | 12214 for (intptr_t i = 1; i <= test_entry_length; i++) { |
| 12198 data.SetAt(data.Length() - i, smi_illegal_cid()); | 12215 data.SetAt(data.Length() - i, smi_illegal_cid()); |
| 12199 } | 12216 } |
| 12200 } | 12217 } |
| 12201 | 12218 |
| 12202 | 12219 |
| 12203 #if defined(DEBUG) | 12220 #if defined(DEBUG) |
| 12204 // Used in asserts to verify that a check is not added twice. | 12221 // Used in asserts to verify that a check is not added twice. |
| 12205 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { | 12222 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { |
| 12206 const intptr_t len = NumberOfChecks(); | 12223 const intptr_t len = NumberOfChecks(); |
| 12207 for (intptr_t i = 0; i < len; i++) { | 12224 for (intptr_t i = 0; i < len; i++) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12240 } | 12257 } |
| 12241 return; | 12258 return; |
| 12242 } | 12259 } |
| 12243 ASSERT(NumArgsTested() == 0); | 12260 ASSERT(NumArgsTested() == 0); |
| 12244 // Can add only once. | 12261 // Can add only once. |
| 12245 const intptr_t old_num = NumberOfChecks(); | 12262 const intptr_t old_num = NumberOfChecks(); |
| 12246 ASSERT(old_num == 0); | 12263 ASSERT(old_num == 0); |
| 12247 Array& data = Array::Handle(ic_data()); | 12264 Array& data = Array::Handle(ic_data()); |
| 12248 const intptr_t new_len = data.Length() + TestEntryLength(); | 12265 const intptr_t new_len = data.Length() + TestEntryLength(); |
| 12249 data = Array::Grow(data, new_len, Heap::kOld); | 12266 data = Array::Grow(data, new_len, Heap::kOld); |
| 12250 set_ic_data(data); | 12267 WriteSentinel(data, TestEntryLength()); |
| 12251 WriteSentinel(data); | |
| 12252 intptr_t data_pos = old_num * TestEntryLength(); | 12268 intptr_t data_pos = old_num * TestEntryLength(); |
| 12253 ASSERT(!target.IsNull()); | 12269 ASSERT(!target.IsNull()); |
| 12254 data.SetAt(data_pos++, target); | 12270 data.SetAt(data_pos++, target); |
| 12255 // Set count to 0 as this is called during compilation, before the | 12271 // Set count to 0 as this is called during compilation, before the |
| 12256 // call has been executed. | 12272 // call has been executed. |
| 12257 const Smi& value = Smi::Handle(Smi::New(0)); | 12273 const Smi& value = Smi::Handle(Smi::New(0)); |
| 12258 data.SetAt(data_pos, value); | 12274 data.SetAt(data_pos, value); |
| 12275 // Multithreaded access to ICData requires setting of array to be the last |
| 12276 // operation. |
| 12277 set_ic_data_array(data); |
| 12259 } | 12278 } |
| 12260 | 12279 |
| 12261 | 12280 |
| 12262 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, | 12281 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, |
| 12263 const Function& target) const { | 12282 const Function& target) const { |
| 12264 ASSERT(!target.IsNull()); | 12283 ASSERT(!target.IsNull()); |
| 12265 ASSERT(target.name() == target_name()); | 12284 ASSERT(target.name() == target_name()); |
| 12266 DEBUG_ASSERT(!HasCheck(class_ids)); | 12285 DEBUG_ASSERT(!HasCheck(class_ids)); |
| 12267 ASSERT(NumArgsTested() > 1); // Otherwise use 'AddReceiverCheck'. | 12286 ASSERT(NumArgsTested() > 1); // Otherwise use 'AddReceiverCheck'. |
| 12268 ASSERT(class_ids.length() == NumArgsTested()); | 12287 ASSERT(class_ids.length() == NumArgsTested()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 12286 for (intptr_t i = 0; i < NumArgsTested(); i++) { | 12305 for (intptr_t i = 0; i < NumArgsTested(); i++) { |
| 12287 ASSERT(class_ids[i] != kIllegalCid); | 12306 ASSERT(class_ids[i] != kIllegalCid); |
| 12288 value = Smi::New(class_ids[i]); | 12307 value = Smi::New(class_ids[i]); |
| 12289 data.SetAt(i, value); | 12308 data.SetAt(i, value); |
| 12290 } | 12309 } |
| 12291 return; | 12310 return; |
| 12292 } | 12311 } |
| 12293 } | 12312 } |
| 12294 const intptr_t new_len = data.Length() + TestEntryLength(); | 12313 const intptr_t new_len = data.Length() + TestEntryLength(); |
| 12295 data = Array::Grow(data, new_len, Heap::kOld); | 12314 data = Array::Grow(data, new_len, Heap::kOld); |
| 12296 set_ic_data(data); | 12315 WriteSentinel(data, TestEntryLength()); |
| 12297 WriteSentinel(data); | |
| 12298 intptr_t data_pos = old_num * TestEntryLength(); | 12316 intptr_t data_pos = old_num * TestEntryLength(); |
| 12299 Smi& value = Smi::Handle(); | 12317 Smi& value = Smi::Handle(); |
| 12300 for (intptr_t i = 0; i < class_ids.length(); i++) { | 12318 for (intptr_t i = 0; i < class_ids.length(); i++) { |
| 12301 // kIllegalCid is used as terminating value, do not add it. | 12319 // kIllegalCid is used as terminating value, do not add it. |
| 12302 ASSERT(class_ids[i] != kIllegalCid); | 12320 ASSERT(class_ids[i] != kIllegalCid); |
| 12303 value = Smi::New(class_ids[i]); | 12321 value = Smi::New(class_ids[i]); |
| 12304 data.SetAt(data_pos++, value); | 12322 data.SetAt(data_pos++, value); |
| 12305 } | 12323 } |
| 12306 ASSERT(!target.IsNull()); | 12324 ASSERT(!target.IsNull()); |
| 12307 data.SetAt(data_pos++, target); | 12325 data.SetAt(data_pos++, target); |
| 12308 value = Smi::New(1); | 12326 value = Smi::New(1); |
| 12309 data.SetAt(data_pos, value); | 12327 data.SetAt(data_pos, value); |
| 12328 // Multithreaded access to ICData requires setting of array to be the last |
| 12329 // operation. |
| 12330 set_ic_data_array(data); |
| 12310 } | 12331 } |
| 12311 | 12332 |
| 12312 | 12333 |
| 12313 void ICData::AddReceiverCheck(intptr_t receiver_class_id, | 12334 void ICData::AddReceiverCheck(intptr_t receiver_class_id, |
| 12314 const Function& target, | 12335 const Function& target, |
| 12315 intptr_t count) const { | 12336 intptr_t count) const { |
| 12316 #if defined(DEBUG) | 12337 #if defined(DEBUG) |
| 12317 GrowableArray<intptr_t> class_ids(1); | 12338 GrowableArray<intptr_t> class_ids(1); |
| 12318 class_ids.Add(receiver_class_id); | 12339 class_ids.Add(receiver_class_id); |
| 12319 ASSERT(!HasCheck(class_ids)); | 12340 ASSERT(!HasCheck(class_ids)); |
| 12320 #endif // DEBUG | 12341 #endif // DEBUG |
| 12321 ASSERT(!target.IsNull()); | 12342 ASSERT(!target.IsNull()); |
| 12322 ASSERT(NumArgsTested() == 1); // Otherwise use 'AddCheck'. | 12343 ASSERT(NumArgsTested() == 1); // Otherwise use 'AddCheck'. |
| 12323 ASSERT(receiver_class_id != kIllegalCid); | 12344 ASSERT(receiver_class_id != kIllegalCid); |
| 12324 | 12345 |
| 12325 const intptr_t old_num = NumberOfChecks(); | 12346 const intptr_t old_num = NumberOfChecks(); |
| 12326 Array& data = Array::Handle(ic_data()); | 12347 Array& data = Array::Handle(ic_data()); |
| 12327 const intptr_t new_len = data.Length() + TestEntryLength(); | 12348 const intptr_t new_len = data.Length() + TestEntryLength(); |
| 12328 data = Array::Grow(data, new_len, Heap::kOld); | 12349 data = Array::Grow(data, new_len, Heap::kOld); |
| 12329 set_ic_data(data); | 12350 WriteSentinel(data, TestEntryLength()); |
| 12330 WriteSentinel(data); | |
| 12331 intptr_t data_pos = old_num * TestEntryLength(); | 12351 intptr_t data_pos = old_num * TestEntryLength(); |
| 12332 if ((receiver_class_id == kSmiCid) && (data_pos > 0)) { | 12352 if ((receiver_class_id == kSmiCid) && (data_pos > 0)) { |
| 12333 ASSERT(GetReceiverClassIdAt(0) != kSmiCid); | 12353 ASSERT(GetReceiverClassIdAt(0) != kSmiCid); |
| 12334 // Move class occupying position 0 to the data_pos. | 12354 // Move class occupying position 0 to the data_pos. |
| 12335 for (intptr_t i = 0; i < TestEntryLength(); i++) { | 12355 for (intptr_t i = 0; i < TestEntryLength(); i++) { |
| 12336 data.SetAt(data_pos + i, Object::Handle(data.At(i))); | 12356 data.SetAt(data_pos + i, Object::Handle(data.At(i))); |
| 12337 } | 12357 } |
| 12338 // Insert kSmiCid in position 0. | 12358 // Insert kSmiCid in position 0. |
| 12339 data_pos = 0; | 12359 data_pos = 0; |
| 12340 } | 12360 } |
| 12341 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); | 12361 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); |
| 12342 data.SetAt(data_pos + 1, target); | 12362 data.SetAt(data_pos + 1, target); |
| 12343 data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count))); | 12363 data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count))); |
| 12364 // Multithreaded access to ICData requires setting of array to be the last |
| 12365 // operation. |
| 12366 set_ic_data_array(data); |
| 12344 } | 12367 } |
| 12345 | 12368 |
| 12346 | 12369 |
| 12347 void ICData::GetCheckAt(intptr_t index, | 12370 void ICData::GetCheckAt(intptr_t index, |
| 12348 GrowableArray<intptr_t>* class_ids, | 12371 GrowableArray<intptr_t>* class_ids, |
| 12349 Function* target) const { | 12372 Function* target) const { |
| 12350 ASSERT(index < NumberOfChecks()); | 12373 ASSERT(index < NumberOfChecks()); |
| 12351 ASSERT(class_ids != NULL); | 12374 ASSERT(class_ids != NULL); |
| 12352 ASSERT(target != NULL); | 12375 ASSERT(target != NULL); |
| 12353 class_ids->Clear(); | 12376 class_ids->Clear(); |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12629 result.set_owner(owner); | 12652 result.set_owner(owner); |
| 12630 result.set_target_name(target_name); | 12653 result.set_target_name(target_name); |
| 12631 result.set_arguments_descriptor(arguments_descriptor); | 12654 result.set_arguments_descriptor(arguments_descriptor); |
| 12632 result.set_deopt_id(deopt_id); | 12655 result.set_deopt_id(deopt_id); |
| 12633 result.set_state_bits(0); | 12656 result.set_state_bits(0); |
| 12634 result.SetNumArgsTested(num_args_tested); | 12657 result.SetNumArgsTested(num_args_tested); |
| 12635 // Number of array elements in one test entry. | 12658 // Number of array elements in one test entry. |
| 12636 intptr_t len = result.TestEntryLength(); | 12659 intptr_t len = result.TestEntryLength(); |
| 12637 // IC data array must be null terminated (sentinel entry). | 12660 // IC data array must be null terminated (sentinel entry). |
| 12638 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); | 12661 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); |
| 12639 result.set_ic_data(ic_data); | 12662 WriteSentinel(ic_data, result.TestEntryLength()); |
| 12640 result.WriteSentinel(ic_data); | 12663 result.set_ic_data_array(ic_data); |
| 12641 return result.raw(); | 12664 return result.raw(); |
| 12642 } | 12665 } |
| 12643 | 12666 |
| 12644 | 12667 |
| 12645 RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) { | 12668 RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) { |
| 12646 const ICData& result = ICData::Handle(ICData::New( | 12669 const ICData& result = ICData::Handle(ICData::New( |
| 12647 Function::Handle(from.owner()), | 12670 Function::Handle(from.owner()), |
| 12648 String::Handle(from.target_name()), | 12671 String::Handle(from.target_name()), |
| 12649 Array::Handle(from.arguments_descriptor()), | 12672 Array::Handle(from.arguments_descriptor()), |
| 12650 from.deopt_id(), | 12673 from.deopt_id(), |
| (...skipping 9105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21756 return tag_label.ToCString(); | 21779 return tag_label.ToCString(); |
| 21757 } | 21780 } |
| 21758 | 21781 |
| 21759 | 21782 |
| 21760 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 21783 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 21761 Instance::PrintJSONImpl(stream, ref); | 21784 Instance::PrintJSONImpl(stream, ref); |
| 21762 } | 21785 } |
| 21763 | 21786 |
| 21764 | 21787 |
| 21765 } // namespace dart | 21788 } // namespace dart |
| OLD | NEW |