| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |