| 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 5410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5421 void Function::set_kind(RawFunction::Kind value) const { | 5421 void Function::set_kind(RawFunction::Kind value) const { |
| 5422 set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_)); | 5422 set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_)); |
| 5423 } | 5423 } |
| 5424 | 5424 |
| 5425 | 5425 |
| 5426 void Function::set_modifier(RawFunction::AsyncModifier value) const { | 5426 void Function::set_modifier(RawFunction::AsyncModifier value) const { |
| 5427 set_kind_tag(ModifierBits::update(value, raw_ptr()->kind_tag_)); | 5427 set_kind_tag(ModifierBits::update(value, raw_ptr()->kind_tag_)); |
| 5428 } | 5428 } |
| 5429 | 5429 |
| 5430 | 5430 |
| 5431 void Function::set_is_intrinsic(bool value) const { | |
| 5432 set_kind_tag(IntrinsicBit::update(value, raw_ptr()->kind_tag_)); | |
| 5433 } | |
| 5434 | |
| 5435 | |
| 5436 void Function::set_recognized_kind(MethodRecognizer::Kind value) const { | 5431 void Function::set_recognized_kind(MethodRecognizer::Kind value) const { |
| 5437 // Prevent multiple settings of kind. | 5432 // Prevent multiple settings of kind. |
| 5438 ASSERT((value == MethodRecognizer::kUnknown) || !IsRecognized()); | 5433 ASSERT((value == MethodRecognizer::kUnknown) || !IsRecognized()); |
| 5439 set_kind_tag(RecognizedBits::update(value, raw_ptr()->kind_tag_)); | 5434 set_kind_tag(RecognizedBits::update(value, raw_ptr()->kind_tag_)); |
| 5440 } | 5435 } |
| 5441 | 5436 |
| 5442 | 5437 |
| 5443 void Function::set_is_redirecting(bool value) const { | |
| 5444 set_kind_tag(RedirectingBit::update(value, raw_ptr()->kind_tag_)); | |
| 5445 } | |
| 5446 | |
| 5447 | |
| 5448 void Function::set_is_static(bool value) const { | |
| 5449 set_kind_tag(StaticBit::update(value, raw_ptr()->kind_tag_)); | |
| 5450 } | |
| 5451 | |
| 5452 | |
| 5453 void Function::set_is_const(bool value) const { | |
| 5454 set_kind_tag(ConstBit::update(value, raw_ptr()->kind_tag_)); | |
| 5455 } | |
| 5456 | |
| 5457 | |
| 5458 void Function::set_is_external(bool value) const { | |
| 5459 set_kind_tag(ExternalBit::update(value, raw_ptr()->kind_tag_)); | |
| 5460 } | |
| 5461 | |
| 5462 | |
| 5463 void Function::set_is_async_closure(bool value) const { | |
| 5464 set_kind_tag(AsyncClosureBit::update(value, raw_ptr()->kind_tag_)); | |
| 5465 // Prohibit inlining as the closure is used for implementing a continuation. | |
| 5466 set_is_inlinable(false); | |
| 5467 } | |
| 5468 | |
| 5469 | |
| 5470 void Function::set_token_pos(intptr_t value) const { | 5438 void Function::set_token_pos(intptr_t value) const { |
| 5471 ASSERT(value >= 0); | 5439 ASSERT(value >= 0); |
| 5472 StoreNonPointer(&raw_ptr()->token_pos_, value); | 5440 StoreNonPointer(&raw_ptr()->token_pos_, value); |
| 5473 } | 5441 } |
| 5474 | 5442 |
| 5475 | 5443 |
| 5476 void Function::set_kind_tag(intptr_t value) const { | 5444 void Function::set_kind_tag(intptr_t value) const { |
| 5477 StoreNonPointer(&raw_ptr()->kind_tag_, static_cast<uint32_t>(value)); | 5445 StoreNonPointer(&raw_ptr()->kind_tag_, static_cast<uint32_t>(value)); |
| 5478 } | 5446 } |
| 5479 | 5447 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5540 } | 5508 } |
| 5541 } | 5509 } |
| 5542 | 5510 |
| 5543 | 5511 |
| 5544 void Function::SetIsNativeAutoSetupScope(bool value) const { | 5512 void Function::SetIsNativeAutoSetupScope(bool value) const { |
| 5545 ASSERT(is_native()); | 5513 ASSERT(is_native()); |
| 5546 set_is_optimizable(value); | 5514 set_is_optimizable(value); |
| 5547 } | 5515 } |
| 5548 | 5516 |
| 5549 | 5517 |
| 5550 void Function::set_is_optimizable(bool value) const { | 5518 bool Function::CanBeInlined() const { |
| 5551 set_kind_tag(OptimizableBit::update(value, raw_ptr()->kind_tag_)); | 5519 return is_inlinable() && |
| 5520 !is_async_closure() && |
| 5521 HasCode() && |
| 5522 !Isolate::Current()->debugger()->HasBreakpoint(*this); |
| 5552 } | 5523 } |
| 5553 | 5524 |
| 5554 | 5525 |
| 5555 void Function::set_allows_hoisting_check_class(bool value) const { | |
| 5556 set_kind_tag( | |
| 5557 AllowsHoistingCheckClassBit::update(value, raw_ptr()->kind_tag_)); | |
| 5558 } | |
| 5559 | |
| 5560 | |
| 5561 void Function::set_is_native(bool value) const { | |
| 5562 set_kind_tag(NativeBit::update(value, raw_ptr()->kind_tag_)); | |
| 5563 } | |
| 5564 | |
| 5565 | |
| 5566 void Function::set_is_abstract(bool value) const { | |
| 5567 set_kind_tag(AbstractBit::update(value, raw_ptr()->kind_tag_)); | |
| 5568 } | |
| 5569 | |
| 5570 | |
| 5571 void Function::set_is_inlinable(bool value) const { | |
| 5572 set_kind_tag(InlinableBit::update(value, raw_ptr()->kind_tag_)); | |
| 5573 } | |
| 5574 | |
| 5575 | |
| 5576 bool Function::IsInlineable() const { | |
| 5577 return (InlinableBit::decode(raw_ptr()->kind_tag_) && | |
| 5578 HasCode() && | |
| 5579 !Isolate::Current()->debugger()->HasBreakpoint(*this)); | |
| 5580 } | |
| 5581 | |
| 5582 | |
| 5583 void Function::set_is_visible(bool value) const { | |
| 5584 set_kind_tag(VisibleBit::update(value, raw_ptr()->kind_tag_)); | |
| 5585 } | |
| 5586 | |
| 5587 | |
| 5588 intptr_t Function::NumParameters() const { | 5526 intptr_t Function::NumParameters() const { |
| 5589 return num_fixed_parameters() + NumOptionalParameters(); | 5527 return num_fixed_parameters() + NumOptionalParameters(); |
| 5590 } | 5528 } |
| 5591 | 5529 |
| 5592 | 5530 |
| 5593 intptr_t Function::NumImplicitParameters() const { | 5531 intptr_t Function::NumImplicitParameters() const { |
| 5594 if (kind() == RawFunction::kConstructor) { | 5532 if (kind() == RawFunction::kConstructor) { |
| 5595 if (is_static()) { | 5533 if (is_static()) { |
| 5596 ASSERT(IsFactory()); | 5534 ASSERT(IsFactory()); |
| 5597 return 1; // Type arguments. | 5535 return 1; // Type arguments. |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6113 result.set_end_token_pos(token_pos); | 6051 result.set_end_token_pos(token_pos); |
| 6114 result.set_num_fixed_parameters(0); | 6052 result.set_num_fixed_parameters(0); |
| 6115 result.set_num_optional_parameters(0); | 6053 result.set_num_optional_parameters(0); |
| 6116 result.set_usage_counter(0); | 6054 result.set_usage_counter(0); |
| 6117 result.set_deoptimization_counter(0); | 6055 result.set_deoptimization_counter(0); |
| 6118 result.set_optimized_instruction_count(0); | 6056 result.set_optimized_instruction_count(0); |
| 6119 result.set_optimized_call_site_count(0); | 6057 result.set_optimized_call_site_count(0); |
| 6120 result.set_is_optimizable(is_native ? false : true); | 6058 result.set_is_optimizable(is_native ? false : true); |
| 6121 result.set_is_inlinable(true); | 6059 result.set_is_inlinable(true); |
| 6122 result.set_allows_hoisting_check_class(true); | 6060 result.set_allows_hoisting_check_class(true); |
| 6061 result.set_allows_bounds_check_generalization(true); |
| 6123 result.SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); | 6062 result.SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); |
| 6124 if (kind == RawFunction::kClosureFunction) { | 6063 if (kind == RawFunction::kClosureFunction) { |
| 6125 const ClosureData& data = ClosureData::Handle(ClosureData::New()); | 6064 const ClosureData& data = ClosureData::Handle(ClosureData::New()); |
| 6126 result.set_data(data); | 6065 result.set_data(data); |
| 6127 } | 6066 } |
| 6128 | 6067 |
| 6129 return result.raw(); | 6068 return result.raw(); |
| 6130 } | 6069 } |
| 6131 | 6070 |
| 6132 | 6071 |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6766 jsobj.AddProperty("parent", parent); | 6705 jsobj.AddProperty("parent", parent); |
| 6767 } | 6706 } |
| 6768 const char* kind_string = Function::KindToCString(kind()); | 6707 const char* kind_string = Function::KindToCString(kind()); |
| 6769 jsobj.AddProperty("kind", kind_string); | 6708 jsobj.AddProperty("kind", kind_string); |
| 6770 if (ref) { | 6709 if (ref) { |
| 6771 return; | 6710 return; |
| 6772 } | 6711 } |
| 6773 jsobj.AddProperty("static", is_static()); | 6712 jsobj.AddProperty("static", is_static()); |
| 6774 jsobj.AddProperty("const", is_const()); | 6713 jsobj.AddProperty("const", is_const()); |
| 6775 jsobj.AddProperty("optimizable", is_optimizable()); | 6714 jsobj.AddProperty("optimizable", is_optimizable()); |
| 6776 jsobj.AddProperty("inlinable", IsInlineable()); | 6715 jsobj.AddProperty("inlinable", CanBeInlined()); |
| 6777 jsobj.AddProperty("unoptimizedCode", Object::Handle(unoptimized_code())); | 6716 jsobj.AddProperty("unoptimizedCode", Object::Handle(unoptimized_code())); |
| 6778 jsobj.AddProperty("usageCounter", usage_counter()); | 6717 jsobj.AddProperty("usageCounter", usage_counter()); |
| 6779 jsobj.AddProperty("optimizedCallSiteCount", optimized_call_site_count()); | 6718 jsobj.AddProperty("optimizedCallSiteCount", optimized_call_site_count()); |
| 6780 jsobj.AddProperty("code", Object::Handle(CurrentCode())); | 6719 jsobj.AddProperty("code", Object::Handle(CurrentCode())); |
| 6781 jsobj.AddProperty("deoptimizations", | 6720 jsobj.AddProperty("deoptimizations", |
| 6782 static_cast<intptr_t>(deoptimization_counter())); | 6721 static_cast<intptr_t>(deoptimization_counter())); |
| 6783 | 6722 |
| 6784 const Script& script = Script::Handle(this->script()); | 6723 const Script& script = Script::Handle(this->script()); |
| 6785 if (!script.IsNull()) { | 6724 if (!script.IsNull()) { |
| 6786 jsobj.AddProperty("script", script); | 6725 jsobj.AddProperty("script", script); |
| (...skipping 4343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11130 } | 11069 } |
| 11131 return pos; | 11070 return pos; |
| 11132 } | 11071 } |
| 11133 | 11072 |
| 11134 | 11073 |
| 11135 void DeoptInfo::ToInstructions(const Array& table, | 11074 void DeoptInfo::ToInstructions(const Array& table, |
| 11136 GrowableArray<DeoptInstr*>* instructions) const { | 11075 GrowableArray<DeoptInstr*>* instructions) const { |
| 11137 ASSERT(instructions->is_empty()); | 11076 ASSERT(instructions->is_empty()); |
| 11138 Smi& offset = Smi::Handle(); | 11077 Smi& offset = Smi::Handle(); |
| 11139 DeoptInfo& info = DeoptInfo::Handle(raw()); | 11078 DeoptInfo& info = DeoptInfo::Handle(raw()); |
| 11140 Smi& reason = Smi::Handle(); | 11079 Smi& reason_and_flags = Smi::Handle(); |
| 11141 intptr_t index = 0; | 11080 intptr_t index = 0; |
| 11142 intptr_t length = TranslationLength(); | 11081 intptr_t length = TranslationLength(); |
| 11143 while (index < length) { | 11082 while (index < length) { |
| 11144 intptr_t instruction = info.Instruction(index); | 11083 intptr_t instruction = info.Instruction(index); |
| 11145 intptr_t from_index = info.FromIndex(index); | 11084 intptr_t from_index = info.FromIndex(index); |
| 11146 if (instruction == DeoptInstr::kSuffix) { | 11085 if (instruction == DeoptInstr::kSuffix) { |
| 11147 // Suffix instructions cause us to 'jump' to another translation, | 11086 // Suffix instructions cause us to 'jump' to another translation, |
| 11148 // changing info, length and index. | 11087 // changing info, length and index. |
| 11149 intptr_t info_number = 0; | 11088 intptr_t info_number = 0; |
| 11150 intptr_t suffix_length = | 11089 intptr_t suffix_length = |
| 11151 DeoptInstr::DecodeSuffix(from_index, &info_number); | 11090 DeoptInstr::DecodeSuffix(from_index, &info_number); |
| 11152 DeoptTable::GetEntry(table, info_number, &offset, &info, &reason); | 11091 DeoptTable::GetEntry( |
| 11092 table, info_number, &offset, &info, &reason_and_flags); |
| 11153 length = info.TranslationLength(); | 11093 length = info.TranslationLength(); |
| 11154 index = length - suffix_length; | 11094 index = length - suffix_length; |
| 11155 } else { | 11095 } else { |
| 11156 instructions->Add(DeoptInstr::Create(instruction, from_index)); | 11096 instructions->Add(DeoptInstr::Create(instruction, from_index)); |
| 11157 ++index; | 11097 ++index; |
| 11158 } | 11098 } |
| 11159 } | 11099 } |
| 11160 } | 11100 } |
| 11161 | 11101 |
| 11162 | 11102 |
| (...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11918 } | 11858 } |
| 11919 #endif // DEBUG | 11859 #endif // DEBUG |
| 11920 } | 11860 } |
| 11921 | 11861 |
| 11922 | 11862 |
| 11923 bool Code::HasBreakpoint() const { | 11863 bool Code::HasBreakpoint() const { |
| 11924 return Isolate::Current()->debugger()->HasBreakpoint(*this); | 11864 return Isolate::Current()->debugger()->HasBreakpoint(*this); |
| 11925 } | 11865 } |
| 11926 | 11866 |
| 11927 | 11867 |
| 11928 RawDeoptInfo* Code::GetDeoptInfoAtPc( | 11868 RawDeoptInfo* Code::GetDeoptInfoAtPc(uword pc, |
| 11929 uword pc, ICData::DeoptReasonId* deopt_reason) const { | 11869 ICData::DeoptReasonId* deopt_reason, |
| 11870 uint32_t* deopt_flags) const { |
| 11930 ASSERT(is_optimized()); | 11871 ASSERT(is_optimized()); |
| 11931 const Instructions& instrs = Instructions::Handle(instructions()); | 11872 const Instructions& instrs = Instructions::Handle(instructions()); |
| 11932 uword code_entry = instrs.EntryPoint(); | 11873 uword code_entry = instrs.EntryPoint(); |
| 11933 const Array& table = Array::Handle(deopt_info_array()); | 11874 const Array& table = Array::Handle(deopt_info_array()); |
| 11934 ASSERT(!table.IsNull()); | 11875 ASSERT(!table.IsNull()); |
| 11935 // Linear search for the PC offset matching the target PC. | 11876 // Linear search for the PC offset matching the target PC. |
| 11936 intptr_t length = DeoptTable::GetLength(table); | 11877 intptr_t length = DeoptTable::GetLength(table); |
| 11937 Smi& offset = Smi::Handle(); | 11878 Smi& offset = Smi::Handle(); |
| 11938 Smi& reason = Smi::Handle(); | 11879 Smi& reason_and_flags = Smi::Handle(); |
| 11939 DeoptInfo& info = DeoptInfo::Handle(); | 11880 DeoptInfo& info = DeoptInfo::Handle(); |
| 11940 for (intptr_t i = 0; i < length; ++i) { | 11881 for (intptr_t i = 0; i < length; ++i) { |
| 11941 DeoptTable::GetEntry(table, i, &offset, &info, &reason); | 11882 DeoptTable::GetEntry(table, i, &offset, &info, &reason_and_flags); |
| 11942 if (pc == (code_entry + offset.Value())) { | 11883 if (pc == (code_entry + offset.Value())) { |
| 11943 ASSERT(!info.IsNull()); | 11884 ASSERT(!info.IsNull()); |
| 11944 ASSERT((0 <= reason.Value()) && | 11885 *deopt_reason = DeoptTable::ReasonField::decode(reason_and_flags.Value()); |
| 11945 (reason.Value() < ICData::kDeoptNumReasons)); | 11886 *deopt_flags = DeoptTable::FlagsField::decode(reason_and_flags.Value()); |
| 11946 *deopt_reason = static_cast<ICData::DeoptReasonId>(reason.Value()); | |
| 11947 return info.raw(); | 11887 return info.raw(); |
| 11948 } | 11888 } |
| 11949 } | 11889 } |
| 11950 *deopt_reason = ICData::kDeoptUnknown; | 11890 *deopt_reason = ICData::kDeoptUnknown; |
| 11951 return DeoptInfo::null(); | 11891 return DeoptInfo::null(); |
| 11952 } | 11892 } |
| 11953 | 11893 |
| 11954 | 11894 |
| 11955 intptr_t Code::BinarySearchInSCallTable(uword pc) const { | 11895 intptr_t Code::BinarySearchInSCallTable(uword pc) const { |
| 11956 NoGCScope no_gc; | 11896 NoGCScope no_gc; |
| (...skipping 8350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20307 return tag_label.ToCString(); | 20247 return tag_label.ToCString(); |
| 20308 } | 20248 } |
| 20309 | 20249 |
| 20310 | 20250 |
| 20311 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 20251 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 20312 Instance::PrintJSONImpl(stream, ref); | 20252 Instance::PrintJSONImpl(stream, ref); |
| 20313 } | 20253 } |
| 20314 | 20254 |
| 20315 | 20255 |
| 20316 } // namespace dart | 20256 } // namespace dart |
| OLD | NEW |