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

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

Issue 22851003: Initial support for length guards on final fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 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
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, 52 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000,
53 "Huge method cutoff in tokens: Disables optimizations for huge methods."); 53 "Huge method cutoff in tokens: Disables optimizations for huge methods.");
54 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, 54 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000,
55 "Huge method cutoff in unoptimized code size (in bytes)."); 55 "Huge method cutoff in unoptimized code size (in bytes).");
56 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, 56 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false,
57 "Throw an exception when the result of an integer calculation will not " 57 "Throw an exception when the result of an integer calculation will not "
58 "fit into a javascript integer."); 58 "fit into a javascript integer.");
59 DECLARE_FLAG(bool, trace_compiler); 59 DECLARE_FLAG(bool, trace_compiler);
60 DECLARE_FLAG(bool, eliminate_type_checks); 60 DECLARE_FLAG(bool, eliminate_type_checks);
61 DECLARE_FLAG(bool, enable_type_checks); 61 DECLARE_FLAG(bool, enable_type_checks);
62 DECLARE_FLAG(bool, trace_deoptimization);
63 DECLARE_FLAG(bool, trace_deoptimization_verbose);
62 DECLARE_FLAG(bool, error_on_bad_override); 64 DECLARE_FLAG(bool, error_on_bad_override);
63 65
64 static const char* kGetterPrefix = "get:"; 66 static const char* kGetterPrefix = "get:";
65 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); 67 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix);
66 static const char* kSetterPrefix = "set:"; 68 static const char* kSetterPrefix = "set:";
67 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); 69 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix);
68 70
69 cpp_vtable Object::handle_vtable_ = 0; 71 cpp_vtable Object::handle_vtable_ = 0;
70 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 }; 72 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 };
71 cpp_vtable Smi::handle_vtable_ = 0; 73 cpp_vtable Smi::handle_vtable_ = 0;
(...skipping 5225 matching lines...) Expand 10 before | Expand all | Expand 10 after
5297 } else { 5299 } else {
5298 result.SetOffset(0); 5300 result.SetOffset(0);
5299 } 5301 }
5300 result.set_is_final(is_final); 5302 result.set_is_final(is_final);
5301 result.set_is_const(is_const); 5303 result.set_is_const(is_const);
5302 result.set_owner(owner); 5304 result.set_owner(owner);
5303 result.set_token_pos(token_pos); 5305 result.set_token_pos(token_pos);
5304 result.set_has_initializer(false); 5306 result.set_has_initializer(false);
5305 result.set_guarded_cid(kIllegalCid); 5307 result.set_guarded_cid(kIllegalCid);
5306 result.set_is_nullable(false); 5308 result.set_is_nullable(false);
5309 result.set_guarded_list_length(Field::kUnknownFixedLength);
5307 result.set_dependent_code(Object::null_array()); 5310 result.set_dependent_code(Object::null_array());
5308 return result.raw(); 5311 return result.raw();
5309 } 5312 }
5310 5313
5311 5314
5312 5315
5313 RawField* Field::Clone(const Class& new_owner) const { 5316 RawField* Field::Clone(const Class& new_owner) const {
5314 Field& clone = Field::Handle(); 5317 Field& clone = Field::Handle();
5315 clone ^= Object::Clone(*this, Heap::kOld); 5318 clone ^= Object::Clone(*this, Heap::kOld);
5316 const Class& owner = Class::Handle(this->owner()); 5319 const Class& owner = Class::Handle(this->owner());
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
5420 set_dependent_code(Object::null_array()); 5423 set_dependent_code(Object::null_array());
5421 5424
5422 // Deoptimize all dependent code on the stack. 5425 // Deoptimize all dependent code on the stack.
5423 Code& code = Code::Handle(); 5426 Code& code = Code::Handle();
5424 { 5427 {
5425 DartFrameIterator iterator; 5428 DartFrameIterator iterator;
5426 StackFrame* frame = iterator.NextFrame(); 5429 StackFrame* frame = iterator.NextFrame();
5427 while (frame != NULL) { 5430 while (frame != NULL) {
5428 code = frame->LookupDartCode(); 5431 code = frame->LookupDartCode();
5429 if (IsDependentCode(code_objects, code)) { 5432 if (IsDependentCode(code_objects, code)) {
5433 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
5434 Function& function = Function::Handle(code.function());
5435 OS::PrintErr("Deoptimizing %s because guard on field %s failed.\n",
5436 function.ToFullyQualifiedCString(),
5437 ToCString());
5438 }
5430 DeoptimizeAt(code, frame->pc()); 5439 DeoptimizeAt(code, frame->pc());
5431 } 5440 }
5432 frame = iterator.NextFrame(); 5441 frame = iterator.NextFrame();
5433 } 5442 }
5434 } 5443 }
5435 5444
5436 // Switch functions that use dependent code to unoptimized code. 5445 // Switch functions that use dependent code to unoptimized code.
5437 WeakProperty& weak_property = WeakProperty::Handle(); 5446 WeakProperty& weak_property = WeakProperty::Handle();
5438 Function& function = Function::Handle(); 5447 Function& function = Function::Handle();
5439 for (intptr_t i = 0; i < code_objects.Length(); i++) { 5448 for (intptr_t i = 0; i < code_objects.Length(); i++) {
5440 weak_property ^= code_objects.At(i); 5449 weak_property ^= code_objects.At(i);
5441 code ^= weak_property.key(); 5450 code ^= weak_property.key();
5442 if (code.IsNull()) { 5451 if (code.IsNull()) {
5443 // Code was garbage collected already. 5452 // Code was garbage collected already.
5444 continue; 5453 continue;
5445 } 5454 }
5446 5455
5447 function ^= code.function(); 5456 function ^= code.function();
5448 // If function uses dependent code switch it to unoptimized. 5457 // If function uses dependent code switch it to unoptimized.
5449 if (function.CurrentCode() == code.raw()) { 5458 if (function.CurrentCode() == code.raw()) {
5450 ASSERT(function.HasOptimizedCode()); 5459 ASSERT(function.HasOptimizedCode());
5460 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
5461 OS::PrintErr("Switching %s to unoptimized code because guard"
5462 " on field %s was violated.\n",
5463 function.ToFullyQualifiedCString(),
5464 ToCString());
5465 }
5451 function.SwitchToUnoptimizedCode(); 5466 function.SwitchToUnoptimizedCode();
5452 } 5467 }
5453 } 5468 }
5454 } 5469 }
5455 5470
5456 5471
5457 void Field::UpdateCid(intptr_t cid) const { 5472 void Field::UpdateCid(intptr_t cid) const {
5458 if (guarded_cid() == kIllegalCid) { 5473 if (guarded_cid() == kIllegalCid) {
5459 // Field is assigned first time. 5474 // Field is assigned first time.
5460 set_guarded_cid(cid); 5475 set_guarded_cid(cid);
(...skipping 19 matching lines...) Expand all
5480 ASSERT(guarded_cid() != cid); 5495 ASSERT(guarded_cid() != cid);
5481 set_guarded_cid(kDynamicCid); 5496 set_guarded_cid(kDynamicCid);
5482 set_is_nullable(true); 5497 set_is_nullable(true);
5483 } 5498 }
5484 5499
5485 // Expected class id or nullability of the field changed. 5500 // Expected class id or nullability of the field changed.
5486 DeoptimizeDependentCode(); 5501 DeoptimizeDependentCode();
5487 } 5502 }
5488 5503
5489 5504
5505 void Field::UpdateLength(intptr_t list_length) const {
5506 ASSERT(is_final() || (!is_final() &&
5507 (list_length < Field::kUnknownFixedLength)));
5508 ASSERT((list_length == Field::kNoFixedLength) ||
5509 (list_length > Field::kUnknownFixedLength));
5510 ASSERT(guarded_cid() != kIllegalCid);
5511
5512 const bool force_invalidate = (guarded_cid() == kDynamicCid) &&
5513 (list_length != Field::kNoFixedLength);
5514
5515 const bool list_length_unknown =
5516 (guarded_list_length() == Field::kUnknownFixedLength);
5517 const bool list_length_changed = (guarded_list_length() != list_length);
5518
5519 if (list_length_unknown && list_length_changed && !force_invalidate) {
5520 // List length set for first time.
5521 set_guarded_list_length(list_length);
5522 return;
5523 }
5524
5525 if (!list_length_changed && !force_invalidate) {
5526 // List length unchanged.
5527 return;
5528 }
5529
5530 // Multiple list lengths assigned here, stop tracking length.
5531 set_guarded_list_length(Field::kNoFixedLength);
5532 DeoptimizeDependentCode();
5533 }
5534
5535
5490 void LiteralToken::set_literal(const String& literal) const { 5536 void LiteralToken::set_literal(const String& literal) const {
5491 StorePointer(&raw_ptr()->literal_, literal.raw()); 5537 StorePointer(&raw_ptr()->literal_, literal.raw());
5492 } 5538 }
5493 5539
5494 5540
5495 void LiteralToken::set_value(const Object& value) const { 5541 void LiteralToken::set_value(const Object& value) const {
5496 StorePointer(&raw_ptr()->value_, value.raw()); 5542 StorePointer(&raw_ptr()->value_, value.raw());
5497 } 5543 }
5498 5544
5499 5545
(...skipping 9163 matching lines...) Expand 10 before | Expand all | Expand 10 after
14663 } 14709 }
14664 14710
14665 14711
14666 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 14712 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
14667 stream->OpenObject(); 14713 stream->OpenObject();
14668 stream->CloseObject(); 14714 stream->CloseObject();
14669 } 14715 }
14670 14716
14671 14717
14672 } // namespace dart 14718 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698