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 5446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5457 return ast_context()->ReturnInstruction(result, expr->id()); | 5457 return ast_context()->ReturnInstruction(result, expr->id()); |
5458 } | 5458 } |
5459 } | 5459 } |
5460 | 5460 |
5461 LookupIterator it(global, variable->name(), LookupIterator::OWN); | 5461 LookupIterator it(global, variable->name(), LookupIterator::OWN); |
5462 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); | 5462 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); |
5463 | 5463 |
5464 if (type == kUseCell) { | 5464 if (type == kUseCell) { |
5465 Handle<PropertyCell> cell = it.GetPropertyCell(); | 5465 Handle<PropertyCell> cell = it.GetPropertyCell(); |
5466 top_info()->dependencies()->AssumePropertyCell(cell); | 5466 top_info()->dependencies()->AssumePropertyCell(cell); |
5467 if (it.property_details().cell_type() == PropertyCellType::kConstant) { | 5467 auto cell_type = it.property_details().cell_type(); |
| 5468 if (cell_type == PropertyCellType::kConstant || |
| 5469 cell_type == PropertyCellType::kUndefined) { |
5468 Handle<Object> constant_object(cell->value(), isolate()); | 5470 Handle<Object> constant_object(cell->value(), isolate()); |
5469 if (constant_object->IsConsString()) { | 5471 if (constant_object->IsConsString()) { |
5470 constant_object = | 5472 constant_object = |
5471 String::Flatten(Handle<String>::cast(constant_object)); | 5473 String::Flatten(Handle<String>::cast(constant_object)); |
5472 } | 5474 } |
5473 HConstant* constant = New<HConstant>(constant_object); | 5475 HConstant* constant = New<HConstant>(constant_object); |
5474 return ast_context()->ReturnInstruction(constant, expr->id()); | 5476 return ast_context()->ReturnInstruction(constant, expr->id()); |
5475 } else { | 5477 } else { |
| 5478 auto access = HObjectAccess::ForPropertyCellValue(); |
| 5479 UniqueSet<Map>* field_maps = nullptr; |
| 5480 if (cell_type == PropertyCellType::kConstantType) { |
| 5481 switch (cell->GetConstantType()) { |
| 5482 case PropertyCellConstantType::kSmi: |
| 5483 access = access.WithRepresentation(Representation::Smi()); |
| 5484 break; |
| 5485 case PropertyCellConstantType::kStableMap: { |
| 5486 // Check that the map really is stable. The heap object could |
| 5487 // have mutated without the cell updating state. In that case, |
| 5488 // make no promises about the loaded value except that it's a |
| 5489 // heap object. |
| 5490 access = |
| 5491 access.WithRepresentation(Representation::HeapObject()); |
| 5492 Handle<Map> map(HeapObject::cast(cell->value())->map()); |
| 5493 if (map->is_stable()) { |
| 5494 field_maps = new (zone()) |
| 5495 UniqueSet<Map>(Unique<Map>::CreateImmovable(map), zone()); |
| 5496 } |
| 5497 break; |
| 5498 } |
| 5499 } |
| 5500 } |
5476 HConstant* cell_constant = Add<HConstant>(cell); | 5501 HConstant* cell_constant = Add<HConstant>(cell); |
5477 HLoadNamedField* instr = New<HLoadNamedField>( | 5502 HLoadNamedField* instr; |
5478 cell_constant, nullptr, HObjectAccess::ForPropertyCellValue()); | 5503 if (field_maps == nullptr) { |
| 5504 instr = New<HLoadNamedField>(cell_constant, nullptr, access); |
| 5505 } else { |
| 5506 instr = New<HLoadNamedField>(cell_constant, nullptr, access, |
| 5507 field_maps, HType::HeapObject()); |
| 5508 } |
5479 instr->ClearDependsOnFlag(kInobjectFields); | 5509 instr->ClearDependsOnFlag(kInobjectFields); |
5480 instr->SetDependsOnFlag(kGlobalVars); | 5510 instr->SetDependsOnFlag(kGlobalVars); |
5481 return ast_context()->ReturnInstruction(instr, expr->id()); | 5511 return ast_context()->ReturnInstruction(instr, expr->id()); |
5482 } | 5512 } |
5483 } else { | 5513 } else { |
5484 HValue* global_object = Add<HLoadNamedField>( | 5514 HValue* global_object = Add<HLoadNamedField>( |
5485 context(), nullptr, | 5515 context(), nullptr, |
5486 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 5516 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
5487 HLoadGlobalGeneric* instr = | 5517 HLoadGlobalGeneric* instr = |
5488 New<HLoadGlobalGeneric>(global_object, | 5518 New<HLoadGlobalGeneric>(global_object, |
(...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6642 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6672 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6643 return; | 6673 return; |
6644 } | 6674 } |
6645 } | 6675 } |
6646 | 6676 |
6647 LookupIterator it(global, var->name(), LookupIterator::OWN); | 6677 LookupIterator it(global, var->name(), LookupIterator::OWN); |
6648 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); | 6678 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); |
6649 if (type == kUseCell) { | 6679 if (type == kUseCell) { |
6650 Handle<PropertyCell> cell = it.GetPropertyCell(); | 6680 Handle<PropertyCell> cell = it.GetPropertyCell(); |
6651 top_info()->dependencies()->AssumePropertyCell(cell); | 6681 top_info()->dependencies()->AssumePropertyCell(cell); |
6652 if (it.property_details().cell_type() == PropertyCellType::kConstant) { | 6682 auto cell_type = it.property_details().cell_type(); |
| 6683 if (cell_type == PropertyCellType::kConstant || |
| 6684 cell_type == PropertyCellType::kUndefined) { |
6653 Handle<Object> constant(cell->value(), isolate()); | 6685 Handle<Object> constant(cell->value(), isolate()); |
6654 if (value->IsConstant()) { | 6686 if (value->IsConstant()) { |
6655 HConstant* c_value = HConstant::cast(value); | 6687 HConstant* c_value = HConstant::cast(value); |
6656 if (!constant.is_identical_to(c_value->handle(isolate()))) { | 6688 if (!constant.is_identical_to(c_value->handle(isolate()))) { |
6657 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, | 6689 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, |
6658 Deoptimizer::EAGER); | 6690 Deoptimizer::EAGER); |
6659 } | 6691 } |
6660 } else { | 6692 } else { |
6661 HValue* c_constant = Add<HConstant>(constant); | 6693 HValue* c_constant = Add<HConstant>(constant); |
6662 IfBuilder builder(this); | 6694 IfBuilder builder(this); |
6663 if (constant->IsNumber()) { | 6695 if (constant->IsNumber()) { |
6664 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); | 6696 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); |
6665 } else { | 6697 } else { |
6666 builder.If<HCompareObjectEqAndBranch>(value, c_constant); | 6698 builder.If<HCompareObjectEqAndBranch>(value, c_constant); |
6667 } | 6699 } |
6668 builder.Then(); | 6700 builder.Then(); |
6669 builder.Else(); | 6701 builder.Else(); |
6670 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, | 6702 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, |
6671 Deoptimizer::EAGER); | 6703 Deoptimizer::EAGER); |
6672 builder.End(); | 6704 builder.End(); |
6673 } | 6705 } |
6674 } | 6706 } |
6675 HConstant* cell_constant = Add<HConstant>(cell); | 6707 HConstant* cell_constant = Add<HConstant>(cell); |
6676 HInstruction* instr = Add<HStoreNamedField>( | 6708 auto access = HObjectAccess::ForPropertyCellValue(); |
6677 cell_constant, HObjectAccess::ForPropertyCellValue(), value); | 6709 if (cell_type == PropertyCellType::kConstantType) { |
| 6710 switch (cell->GetConstantType()) { |
| 6711 case PropertyCellConstantType::kSmi: |
| 6712 access = access.WithRepresentation(Representation::Smi()); |
| 6713 break; |
| 6714 case PropertyCellConstantType::kStableMap: { |
| 6715 // The map may no longer be stable, deopt if it's ever different from |
| 6716 // what is currently there, which will allow for restablization. |
| 6717 Handle<Map> map(HeapObject::cast(cell->value())->map()); |
| 6718 Add<HCheckHeapObject>(value); |
| 6719 value = Add<HCheckMaps>(value, map); |
| 6720 access = access.WithRepresentation(Representation::HeapObject()); |
| 6721 break; |
| 6722 } |
| 6723 } |
| 6724 } |
| 6725 HInstruction* instr = Add<HStoreNamedField>(cell_constant, access, value); |
6678 instr->ClearChangesFlag(kInobjectFields); | 6726 instr->ClearChangesFlag(kInobjectFields); |
6679 instr->SetChangesFlag(kGlobalVars); | 6727 instr->SetChangesFlag(kGlobalVars); |
6680 if (instr->HasObservableSideEffects()) { | 6728 if (instr->HasObservableSideEffects()) { |
6681 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6729 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6682 } | 6730 } |
6683 } else { | 6731 } else { |
6684 HValue* global_object = Add<HLoadNamedField>( | 6732 HValue* global_object = Add<HLoadNamedField>( |
6685 context(), nullptr, | 6733 context(), nullptr, |
6686 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 6734 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
6687 HStoreNamedGeneric* instr = | 6735 HStoreNamedGeneric* instr = |
(...skipping 6393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13081 if (ShouldProduceTraceOutput()) { | 13129 if (ShouldProduceTraceOutput()) { |
13082 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13130 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13083 } | 13131 } |
13084 | 13132 |
13085 #ifdef DEBUG | 13133 #ifdef DEBUG |
13086 graph_->Verify(false); // No full verify. | 13134 graph_->Verify(false); // No full verify. |
13087 #endif | 13135 #endif |
13088 } | 13136 } |
13089 | 13137 |
13090 } } // namespace v8::internal | 13138 } } // namespace v8::internal |
OLD | NEW |