Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 5378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5389 HObjectAccess::ForContextSlot(lookup.slot_index)); | 5389 HObjectAccess::ForContextSlot(lookup.slot_index)); |
| 5390 return ast_context()->ReturnInstruction(result, expr->id()); | 5390 return ast_context()->ReturnInstruction(result, expr->id()); |
| 5391 } | 5391 } |
| 5392 } | 5392 } |
| 5393 | 5393 |
| 5394 LookupIterator it(global, variable->name(), LookupIterator::OWN); | 5394 LookupIterator it(global, variable->name(), LookupIterator::OWN); |
| 5395 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); | 5395 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); |
| 5396 | 5396 |
| 5397 if (type == kUseCell) { | 5397 if (type == kUseCell) { |
| 5398 Handle<PropertyCell> cell = it.GetPropertyCell(); | 5398 Handle<PropertyCell> cell = it.GetPropertyCell(); |
| 5399 PropertyCell::AddDependentCompilationInfo(cell, top_info()); | 5399 auto cell_type = it.property_details().cell_type(); |
| 5400 if (it.property_details().cell_type() == PropertyCellType::kConstant) { | 5400 if (cell_type == PropertyCellType::kConstant || |
| 5401 cell_type == PropertyCellType::kUndefined) { | |
| 5402 PropertyCell::AddDependentCompilationInfo(cell, top_info()); | |
| 5401 Handle<Object> constant_object(cell->value(), isolate()); | 5403 Handle<Object> constant_object(cell->value(), isolate()); |
| 5402 if (constant_object->IsConsString()) { | 5404 if (constant_object->IsConsString()) { |
| 5403 constant_object = | 5405 constant_object = |
| 5404 String::Flatten(Handle<String>::cast(constant_object)); | 5406 String::Flatten(Handle<String>::cast(constant_object)); |
| 5405 } | 5407 } |
| 5406 HConstant* constant = New<HConstant>(constant_object); | 5408 HConstant* constant = New<HConstant>(constant_object); |
| 5407 return ast_context()->ReturnInstruction(constant, expr->id()); | 5409 return ast_context()->ReturnInstruction(constant, expr->id()); |
| 5408 } else { | 5410 } else { |
| 5411 auto access = HObjectAccess::ForPropertyCellValue(); | |
| 5412 UniqueSet<Map>* field_maps = nullptr; | |
| 5413 if (cell_type == PropertyCellType::kConstantType) { | |
| 5414 switch (cell->GetConstantType()) { | |
| 5415 case PropertyCellConstantType::kSmi: | |
| 5416 access = access.WithRepresentation(Representation::Smi()); | |
| 5417 break; | |
| 5418 case PropertyCellConstantType::kStableMap: { | |
| 5419 // Check that the map really is stable. The heap object could | |
| 5420 // have mutated without the cell updating state. | |
| 5421 Handle<Map> map(HeapObject::cast(cell->value())->map()); | |
| 5422 if (map->is_stable()) { | |
| 5423 access = | |
| 5424 access.WithRepresentation(Representation::HeapObject()); | |
| 5425 field_maps = new (zone()) | |
| 5426 UniqueSet<Map>(Unique<Map>::CreateImmovable(map), zone()); | |
| 5427 } else { | |
| 5428 // TODO(dcarney): bailout here or deopt? | |
| 5429 auto dictionary = handle(global->property_dictionary()); | |
| 5430 cell = PropertyCell::InvalidateEntry(dictionary, | |
| 5431 it.dictionary_entry()); | |
| 5432 } | |
| 5433 break; | |
| 5434 } | |
| 5435 } | |
| 5436 } | |
| 5437 PropertyCell::AddDependentCompilationInfo(cell, top_info()); | |
| 5409 HConstant* cell_constant = Add<HConstant>(cell); | 5438 HConstant* cell_constant = Add<HConstant>(cell); |
| 5410 HLoadNamedField* instr = New<HLoadNamedField>( | 5439 HLoadNamedField* instr; |
| 5411 cell_constant, nullptr, HObjectAccess::ForPropertyCellValue()); | 5440 if (field_maps == nullptr) { |
| 5441 instr = New<HLoadNamedField>(cell_constant, nullptr, access); | |
| 5442 } else { | |
| 5443 instr = New<HLoadNamedField>(cell_constant, nullptr, access, | |
| 5444 field_maps, HType::HeapObject()); | |
| 5445 } | |
| 5412 instr->ClearDependsOnFlag(kInobjectFields); | 5446 instr->ClearDependsOnFlag(kInobjectFields); |
| 5413 instr->SetDependsOnFlag(kGlobalVars); | 5447 instr->SetDependsOnFlag(kGlobalVars); |
| 5414 return ast_context()->ReturnInstruction(instr, expr->id()); | 5448 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5415 } | 5449 } |
| 5416 } else { | 5450 } else { |
| 5417 HValue* global_object = Add<HLoadNamedField>( | 5451 HValue* global_object = Add<HLoadNamedField>( |
| 5418 context(), nullptr, | 5452 context(), nullptr, |
| 5419 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 5453 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 5420 HLoadGlobalGeneric* instr = | 5454 HLoadGlobalGeneric* instr = |
| 5421 New<HLoadGlobalGeneric>(global_object, | 5455 New<HLoadGlobalGeneric>(global_object, |
| (...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6557 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6591 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| 6558 return; | 6592 return; |
| 6559 } | 6593 } |
| 6560 } | 6594 } |
| 6561 | 6595 |
| 6562 LookupIterator it(global, var->name(), LookupIterator::OWN); | 6596 LookupIterator it(global, var->name(), LookupIterator::OWN); |
| 6563 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); | 6597 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); |
| 6564 if (type == kUseCell) { | 6598 if (type == kUseCell) { |
| 6565 Handle<PropertyCell> cell = it.GetPropertyCell(); | 6599 Handle<PropertyCell> cell = it.GetPropertyCell(); |
| 6566 PropertyCell::AddDependentCompilationInfo(cell, top_info()); | 6600 PropertyCell::AddDependentCompilationInfo(cell, top_info()); |
| 6567 if (it.property_details().cell_type() == PropertyCellType::kConstant) { | 6601 auto cell_type = it.property_details().cell_type(); |
| 6602 if (cell_type == PropertyCellType::kConstant || | |
| 6603 cell_type == PropertyCellType::kUndefined) { | |
| 6568 Handle<Object> constant(cell->value(), isolate()); | 6604 Handle<Object> constant(cell->value(), isolate()); |
| 6569 if (value->IsConstant()) { | 6605 if (value->IsConstant()) { |
| 6570 HConstant* c_value = HConstant::cast(value); | 6606 HConstant* c_value = HConstant::cast(value); |
| 6571 if (!constant.is_identical_to(c_value->handle(isolate()))) { | 6607 if (!constant.is_identical_to(c_value->handle(isolate()))) { |
| 6572 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, | 6608 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, |
| 6573 Deoptimizer::EAGER); | 6609 Deoptimizer::EAGER); |
| 6574 } | 6610 } |
| 6575 } else { | 6611 } else { |
| 6576 HValue* c_constant = Add<HConstant>(constant); | 6612 HValue* c_constant = Add<HConstant>(constant); |
| 6577 IfBuilder builder(this); | 6613 IfBuilder builder(this); |
| 6578 if (constant->IsNumber()) { | 6614 if (constant->IsNumber()) { |
| 6579 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); | 6615 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); |
| 6580 } else { | 6616 } else { |
| 6581 builder.If<HCompareObjectEqAndBranch>(value, c_constant); | 6617 builder.If<HCompareObjectEqAndBranch>(value, c_constant); |
| 6582 } | 6618 } |
| 6583 builder.Then(); | 6619 builder.Then(); |
| 6584 builder.Else(); | 6620 builder.Else(); |
| 6585 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, | 6621 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, |
| 6586 Deoptimizer::EAGER); | 6622 Deoptimizer::EAGER); |
| 6587 builder.End(); | 6623 builder.End(); |
| 6588 } | 6624 } |
| 6589 } | 6625 } |
| 6590 HConstant* cell_constant = Add<HConstant>(cell); | 6626 HConstant* cell_constant = Add<HConstant>(cell); |
| 6591 HInstruction* instr = Add<HStoreNamedField>( | 6627 auto access = HObjectAccess::ForPropertyCellValue(); |
| 6592 cell_constant, HObjectAccess::ForPropertyCellValue(), value); | 6628 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE; |
| 6629 if (cell_type == PropertyCellType::kConstantType) { | |
| 6630 // store_mode = STORE_TO_INITIALIZED_ENTRY; | |
| 6631 switch (cell->GetConstantType()) { | |
| 6632 case PropertyCellConstantType::kSmi: | |
| 6633 Add<HCheckSmi>(value); | |
|
dcarney
2015/04/21 07:20:07
same questions as in the code stub
| |
| 6634 access = access.WithRepresentation(Representation::Smi()); | |
| 6635 break; | |
| 6636 case PropertyCellConstantType::kStableMap: { | |
| 6637 // Check that the map really is stable. The heap object could have | |
| 6638 // mutated without the cell updating state. | |
| 6639 Handle<Map> map(HeapObject::cast(cell->value())->map()); | |
| 6640 if (map->is_stable()) { | |
| 6641 Add<HCheckHeapObject>(value); | |
| 6642 value = Add<HCheckMaps>(value, map); | |
| 6643 access = access.WithRepresentation(Representation::HeapObject()); | |
| 6644 } else { | |
| 6645 // TODO(dcarney): bailout here or deopt? | |
|
dcarney
2015/04/21 07:20:07
what to do here and above?
| |
| 6646 auto dictionary = handle(global->property_dictionary()); | |
| 6647 cell = PropertyCell::InvalidateEntry(dictionary, | |
| 6648 it.dictionary_entry()); | |
| 6649 } | |
| 6650 break; | |
| 6651 } | |
| 6652 } | |
| 6653 } | |
| 6654 HInstruction* instr = | |
| 6655 Add<HStoreNamedField>(cell_constant, access, value, store_mode); | |
| 6593 instr->ClearChangesFlag(kInobjectFields); | 6656 instr->ClearChangesFlag(kInobjectFields); |
| 6594 instr->SetChangesFlag(kGlobalVars); | 6657 instr->SetChangesFlag(kGlobalVars); |
| 6595 if (instr->HasObservableSideEffects()) { | 6658 if (instr->HasObservableSideEffects()) { |
| 6596 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6659 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| 6597 } | 6660 } |
| 6598 } else { | 6661 } else { |
| 6599 HValue* global_object = Add<HLoadNamedField>( | 6662 HValue* global_object = Add<HLoadNamedField>( |
| 6600 context(), nullptr, | 6663 context(), nullptr, |
| 6601 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 6664 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 6602 HStoreNamedGeneric* instr = | 6665 HStoreNamedGeneric* instr = |
| (...skipping 6362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12965 if (ShouldProduceTraceOutput()) { | 13028 if (ShouldProduceTraceOutput()) { |
| 12966 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13029 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12967 } | 13030 } |
| 12968 | 13031 |
| 12969 #ifdef DEBUG | 13032 #ifdef DEBUG |
| 12970 graph_->Verify(false); // No full verify. | 13033 graph_->Verify(false); // No full verify. |
| 12971 #endif | 13034 #endif |
| 12972 } | 13035 } |
| 12973 | 13036 |
| 12974 } } // namespace v8::internal | 13037 } } // namespace v8::internal |
| OLD | NEW |