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 619903002: Generalize bounds checks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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 | Annotate | Revision Log
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"
(...skipping 5410 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698