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 top_info()->dependencies()->AssumePropertyCell(cell); | 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 top_info()->dependencies()->AssumePropertyCell(cell); |
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 auto dictionary = handle(global->property_dictionary()); |
| 5429 cell = PropertyCell::InvalidateEntry(dictionary, |
| 5430 it.dictionary_entry()); |
| 5431 } |
| 5432 break; |
| 5433 } |
| 5434 } |
| 5435 } |
| 5436 top_info()->dependencies()->AssumePropertyCell(cell); |
5409 HConstant* cell_constant = Add<HConstant>(cell); | 5437 HConstant* cell_constant = Add<HConstant>(cell); |
5410 HLoadNamedField* instr = New<HLoadNamedField>( | 5438 HLoadNamedField* instr; |
5411 cell_constant, nullptr, HObjectAccess::ForPropertyCellValue()); | 5439 if (field_maps == nullptr) { |
| 5440 instr = New<HLoadNamedField>(cell_constant, nullptr, access); |
| 5441 } else { |
| 5442 instr = New<HLoadNamedField>(cell_constant, nullptr, access, |
| 5443 field_maps, HType::HeapObject()); |
| 5444 } |
5412 instr->ClearDependsOnFlag(kInobjectFields); | 5445 instr->ClearDependsOnFlag(kInobjectFields); |
5413 instr->SetDependsOnFlag(kGlobalVars); | 5446 instr->SetDependsOnFlag(kGlobalVars); |
5414 return ast_context()->ReturnInstruction(instr, expr->id()); | 5447 return ast_context()->ReturnInstruction(instr, expr->id()); |
5415 } | 5448 } |
5416 } else { | 5449 } else { |
5417 HValue* global_object = Add<HLoadNamedField>( | 5450 HValue* global_object = Add<HLoadNamedField>( |
5418 context(), nullptr, | 5451 context(), nullptr, |
5419 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 5452 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
5420 HLoadGlobalGeneric* instr = | 5453 HLoadGlobalGeneric* instr = |
5421 New<HLoadGlobalGeneric>(global_object, | 5454 New<HLoadGlobalGeneric>(global_object, |
(...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6556 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6589 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6557 return; | 6590 return; |
6558 } | 6591 } |
6559 } | 6592 } |
6560 | 6593 |
6561 LookupIterator it(global, var->name(), LookupIterator::OWN); | 6594 LookupIterator it(global, var->name(), LookupIterator::OWN); |
6562 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); | 6595 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); |
6563 if (type == kUseCell) { | 6596 if (type == kUseCell) { |
6564 Handle<PropertyCell> cell = it.GetPropertyCell(); | 6597 Handle<PropertyCell> cell = it.GetPropertyCell(); |
6565 top_info()->dependencies()->AssumePropertyCell(cell); | 6598 top_info()->dependencies()->AssumePropertyCell(cell); |
6566 if (it.property_details().cell_type() == PropertyCellType::kConstant) { | 6599 auto cell_type = it.property_details().cell_type(); |
| 6600 if (cell_type == PropertyCellType::kConstant || |
| 6601 cell_type == PropertyCellType::kUndefined) { |
6567 Handle<Object> constant(cell->value(), isolate()); | 6602 Handle<Object> constant(cell->value(), isolate()); |
6568 if (value->IsConstant()) { | 6603 if (value->IsConstant()) { |
6569 HConstant* c_value = HConstant::cast(value); | 6604 HConstant* c_value = HConstant::cast(value); |
6570 if (!constant.is_identical_to(c_value->handle(isolate()))) { | 6605 if (!constant.is_identical_to(c_value->handle(isolate()))) { |
6571 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, | 6606 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, |
6572 Deoptimizer::EAGER); | 6607 Deoptimizer::EAGER); |
6573 } | 6608 } |
6574 } else { | 6609 } else { |
6575 HValue* c_constant = Add<HConstant>(constant); | 6610 HValue* c_constant = Add<HConstant>(constant); |
6576 IfBuilder builder(this); | 6611 IfBuilder builder(this); |
6577 if (constant->IsNumber()) { | 6612 if (constant->IsNumber()) { |
6578 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); | 6613 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); |
6579 } else { | 6614 } else { |
6580 builder.If<HCompareObjectEqAndBranch>(value, c_constant); | 6615 builder.If<HCompareObjectEqAndBranch>(value, c_constant); |
6581 } | 6616 } |
6582 builder.Then(); | 6617 builder.Then(); |
6583 builder.Else(); | 6618 builder.Else(); |
6584 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, | 6619 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, |
6585 Deoptimizer::EAGER); | 6620 Deoptimizer::EAGER); |
6586 builder.End(); | 6621 builder.End(); |
6587 } | 6622 } |
6588 } | 6623 } |
6589 HConstant* cell_constant = Add<HConstant>(cell); | 6624 HConstant* cell_constant = Add<HConstant>(cell); |
6590 HInstruction* instr = Add<HStoreNamedField>( | 6625 auto access = HObjectAccess::ForPropertyCellValue(); |
6591 cell_constant, HObjectAccess::ForPropertyCellValue(), value); | 6626 if (cell_type == PropertyCellType::kConstantType) { |
| 6627 switch (cell->GetConstantType()) { |
| 6628 case PropertyCellConstantType::kSmi: |
| 6629 access = access.WithRepresentation(Representation::Smi()); |
| 6630 break; |
| 6631 case PropertyCellConstantType::kStableMap: { |
| 6632 // Check that the map really is stable. The heap object could have |
| 6633 // mutated without the cell updating state. |
| 6634 Handle<Map> map(HeapObject::cast(cell->value())->map()); |
| 6635 if (map->is_stable()) { |
| 6636 Add<HCheckHeapObject>(value); |
| 6637 value = Add<HCheckMaps>(value, map); |
| 6638 access = access.WithRepresentation(Representation::HeapObject()); |
| 6639 } else { |
| 6640 auto dictionary = handle(global->property_dictionary()); |
| 6641 cell = PropertyCell::InvalidateEntry(dictionary, |
| 6642 it.dictionary_entry()); |
| 6643 } |
| 6644 break; |
| 6645 } |
| 6646 } |
| 6647 } |
| 6648 HInstruction* instr = Add<HStoreNamedField>(cell_constant, access, value); |
6592 instr->ClearChangesFlag(kInobjectFields); | 6649 instr->ClearChangesFlag(kInobjectFields); |
6593 instr->SetChangesFlag(kGlobalVars); | 6650 instr->SetChangesFlag(kGlobalVars); |
6594 if (instr->HasObservableSideEffects()) { | 6651 if (instr->HasObservableSideEffects()) { |
6595 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6652 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6596 } | 6653 } |
6597 } else { | 6654 } else { |
6598 HValue* global_object = Add<HLoadNamedField>( | 6655 HValue* global_object = Add<HLoadNamedField>( |
6599 context(), nullptr, | 6656 context(), nullptr, |
6600 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 6657 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
6601 HStoreNamedGeneric* instr = | 6658 HStoreNamedGeneric* instr = |
(...skipping 6376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12978 if (ShouldProduceTraceOutput()) { | 13035 if (ShouldProduceTraceOutput()) { |
12979 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13036 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
12980 } | 13037 } |
12981 | 13038 |
12982 #ifdef DEBUG | 13039 #ifdef DEBUG |
12983 graph_->Verify(false); // No full verify. | 13040 graph_->Verify(false); // No full verify. |
12984 #endif | 13041 #endif |
12985 } | 13042 } |
12986 | 13043 |
12987 } } // namespace v8::internal | 13044 } } // namespace v8::internal |
OLD | NEW |