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

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

Issue 99573005: Add mutable double boxes for fields. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 3488 matching lines...) Expand 10 before | Expand all | Expand 10 after
3499 ASSERT((cid == kOneByteStringCid) || (cid == kTwoByteStringCid) || 3499 ASSERT((cid == kOneByteStringCid) || (cid == kTwoByteStringCid) ||
3500 (cid == kExternalOneByteStringCid) || 3500 (cid == kExternalOneByteStringCid) ||
3501 (cid == kGrowableObjectArrayCid) || 3501 (cid == kGrowableObjectArrayCid) ||
3502 (cid == kImmutableArrayCid) || (cid == kArrayCid)); 3502 (cid == kImmutableArrayCid) || (cid == kArrayCid));
3503 ConstantInstr* cid_instr = new ConstantInstr(Smi::Handle(Smi::New(cid))); 3503 ConstantInstr* cid_instr = new ConstantInstr(Smi::Handle(Smi::New(cid)));
3504 ReplaceCall(call, cid_instr); 3504 ReplaceCall(call, cid_instr);
3505 } 3505 }
3506 } 3506 }
3507 3507
3508 3508
3509 void FlowGraphOptimizer::VisitStoreInstanceField(
3510 StoreInstanceFieldInstr* instr) {
3511 if (instr->IsUnboxedStore()) {
3512 ASSERT(instr->initialization_);
3513 // Determine if this field should be unboxed based on the usage of getter
3514 // and setter functions.
3515 const Field& field = Field::ZoneHandle(instr->field().raw());
3516 const String& field_name = String::Handle(field.name());
3517 class Class& owner = Class::Handle(field.owner());
3518 const Function& getter =
3519 Function::Handle(owner.LookupGetterFunction(field_name));
3520 const Function& setter =
3521 Function::Handle(owner.LookupSetterFunction(field_name));
srdjan 2013/12/13 22:12:06 Below is an important heuristic, add brief comment
Florian Schneider 2013/12/16 13:08:09 Done.
3522 bool result = !getter.IsNull()
3523 && !setter.IsNull()
3524 && setter.usage_counter() > 0
srdjan 2013/12/13 18:13:17 Add parentheses here and below.
Florian Schneider 2013/12/16 13:08:09 Done.
3525 && 10 * setter.usage_counter() > getter.usage_counter();
srdjan 2013/12/13 22:12:06 put 10 into a flag to experiment with ?
Florian Schneider 2013/12/16 13:08:09 Done.
3526 if (!result) {
3527 field.set_is_unboxing_candidate(false);
3528 field.DeoptimizeDependentCode();
3529 } else {
3530 FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field);
3531 }
3532 }
3533 }
3534
3535
3509 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, 3536 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr,
3510 const ICData& unary_ic_data) { 3537 const ICData& unary_ic_data) {
3511 ASSERT((unary_ic_data.NumberOfChecks() > 0) && 3538 ASSERT((unary_ic_data.NumberOfChecks() > 0) &&
3512 (unary_ic_data.num_args_tested() == 1)); 3539 (unary_ic_data.num_args_tested() == 1));
3513 if (FLAG_enable_type_checks) { 3540 if (FLAG_enable_type_checks) {
3514 // Checked mode setters are inlined like normal methods by conventional 3541 // Checked mode setters are inlined like normal methods by conventional
3515 // inlining. 3542 // inlining.
3516 return false; 3543 return false;
3517 } 3544 }
3518 3545
(...skipping 10 matching lines...) Expand all
3529 Function& target = Function::Handle(); 3556 Function& target = Function::Handle();
3530 intptr_t class_id; 3557 intptr_t class_id;
3531 unary_ic_data.GetOneClassCheckAt(0, &class_id, &target); 3558 unary_ic_data.GetOneClassCheckAt(0, &class_id, &target);
3532 if (target.kind() != RawFunction::kImplicitSetter) { 3559 if (target.kind() != RawFunction::kImplicitSetter) {
3533 // Non-implicit setter are inlined like normal method calls. 3560 // Non-implicit setter are inlined like normal method calls.
3534 return false; 3561 return false;
3535 } 3562 }
3536 // Inline implicit instance setter. 3563 // Inline implicit instance setter.
3537 const String& field_name = 3564 const String& field_name =
3538 String::Handle(Field::NameFromSetter(instr->function_name())); 3565 String::Handle(Field::NameFromSetter(instr->function_name()));
3539 const Field& field = Field::Handle(GetField(class_id, field_name)); 3566 const Field& field = Field::ZoneHandle(GetField(class_id, field_name));
3540 ASSERT(!field.IsNull()); 3567 ASSERT(!field.IsNull());
3541 3568
3542 if (InstanceCallNeedsClassCheck(instr)) { 3569 if (InstanceCallNeedsClassCheck(instr)) {
3543 AddReceiverCheck(instr); 3570 AddReceiverCheck(instr);
3544 } 3571 }
3545 StoreBarrierType needs_store_barrier = kEmitStoreBarrier; 3572 StoreBarrierType needs_store_barrier = kEmitStoreBarrier;
3546 if (ArgIsAlways(kSmiCid, *instr->ic_data(), 1)) { 3573 if (ArgIsAlways(kSmiCid, *instr->ic_data(), 1)) {
3547 InsertBefore(instr, 3574 InsertBefore(instr,
3548 new CheckSmiInstr(new Value(instr->ArgumentAt(1)), 3575 new CheckSmiInstr(new Value(instr->ArgumentAt(1)),
3549 instr->deopt_id()), 3576 instr->deopt_id()),
(...skipping 10 matching lines...) Expand all
3560 instr->env(), 3587 instr->env(),
3561 Definition::kEffect); 3588 Definition::kEffect);
3562 } 3589 }
3563 3590
3564 // Field guard was detached. 3591 // Field guard was detached.
3565 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr( 3592 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr(
3566 field, 3593 field,
3567 new Value(instr->ArgumentAt(0)), 3594 new Value(instr->ArgumentAt(0)),
3568 new Value(instr->ArgumentAt(1)), 3595 new Value(instr->ArgumentAt(1)),
3569 needs_store_barrier); 3596 needs_store_barrier);
3597
3598 if (store->IsUnboxedStore()) {
3599 FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field);
3600 }
3601
3570 // Discard the environment from the original instruction because the store 3602 // Discard the environment from the original instruction because the store
3571 // can't deoptimize. 3603 // can't deoptimize.
3572 instr->RemoveEnvironment(); 3604 instr->RemoveEnvironment();
3573 ReplaceCall(instr, store); 3605 ReplaceCall(instr, store);
3574 return true; 3606 return true;
3575 } 3607 }
3576 3608
3577 3609
3578 // Range analysis for smi values. 3610 // Range analysis for smi values.
3579 class RangeAnalysis : public ValueObject { 3611 class RangeAnalysis : public ValueObject {
(...skipping 4467 matching lines...) Expand 10 before | Expand all | Expand 10 after
8047 } 8079 }
8048 8080
8049 // Insert materializations at environment uses. 8081 // Insert materializations at environment uses.
8050 for (intptr_t i = 0; i < exits.length(); i++) { 8082 for (intptr_t i = 0; i < exits.length(); i++) {
8051 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 8083 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
8052 } 8084 }
8053 } 8085 }
8054 8086
8055 8087
8056 } // namespace dart 8088 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698