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 auto cell_type = it.property_details().cell_type(); | 5399 top_info()->dependencies()->AssumePropertyCell(cell); |
5400 if (cell_type == PropertyCellType::kConstant || | 5400 if (it.property_details().cell_type() == PropertyCellType::kConstant) { |
5401 cell_type == PropertyCellType::kUndefined) { | |
5402 top_info()->dependencies()->AssumePropertyCell(cell); | |
5403 Handle<Object> constant_object(cell->value(), isolate()); | 5401 Handle<Object> constant_object(cell->value(), isolate()); |
5404 if (constant_object->IsConsString()) { | 5402 if (constant_object->IsConsString()) { |
5405 constant_object = | 5403 constant_object = |
5406 String::Flatten(Handle<String>::cast(constant_object)); | 5404 String::Flatten(Handle<String>::cast(constant_object)); |
5407 } | 5405 } |
5408 HConstant* constant = New<HConstant>(constant_object); | 5406 HConstant* constant = New<HConstant>(constant_object); |
5409 return ast_context()->ReturnInstruction(constant, expr->id()); | 5407 return ast_context()->ReturnInstruction(constant, expr->id()); |
5410 } else { | 5408 } 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); | |
5437 HConstant* cell_constant = Add<HConstant>(cell); | 5409 HConstant* cell_constant = Add<HConstant>(cell); |
5438 HLoadNamedField* instr; | 5410 HLoadNamedField* instr = New<HLoadNamedField>( |
5439 if (field_maps == nullptr) { | 5411 cell_constant, nullptr, HObjectAccess::ForPropertyCellValue()); |
5440 instr = New<HLoadNamedField>(cell_constant, nullptr, access); | |
5441 } else { | |
5442 instr = New<HLoadNamedField>(cell_constant, nullptr, access, | |
5443 field_maps, HType::HeapObject()); | |
5444 } | |
5445 instr->ClearDependsOnFlag(kInobjectFields); | 5412 instr->ClearDependsOnFlag(kInobjectFields); |
5446 instr->SetDependsOnFlag(kGlobalVars); | 5413 instr->SetDependsOnFlag(kGlobalVars); |
5447 return ast_context()->ReturnInstruction(instr, expr->id()); | 5414 return ast_context()->ReturnInstruction(instr, expr->id()); |
5448 } | 5415 } |
5449 } else { | 5416 } else { |
5450 HValue* global_object = Add<HLoadNamedField>( | 5417 HValue* global_object = Add<HLoadNamedField>( |
5451 context(), nullptr, | 5418 context(), nullptr, |
5452 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 5419 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
5453 HLoadGlobalGeneric* instr = | 5420 HLoadGlobalGeneric* instr = |
5454 New<HLoadGlobalGeneric>(global_object, | 5421 New<HLoadGlobalGeneric>(global_object, |
(...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6589 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6556 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6590 return; | 6557 return; |
6591 } | 6558 } |
6592 } | 6559 } |
6593 | 6560 |
6594 LookupIterator it(global, var->name(), LookupIterator::OWN); | 6561 LookupIterator it(global, var->name(), LookupIterator::OWN); |
6595 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); | 6562 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); |
6596 if (type == kUseCell) { | 6563 if (type == kUseCell) { |
6597 Handle<PropertyCell> cell = it.GetPropertyCell(); | 6564 Handle<PropertyCell> cell = it.GetPropertyCell(); |
6598 top_info()->dependencies()->AssumePropertyCell(cell); | 6565 top_info()->dependencies()->AssumePropertyCell(cell); |
6599 auto cell_type = it.property_details().cell_type(); | 6566 if (it.property_details().cell_type() == PropertyCellType::kConstant) { |
6600 if (cell_type == PropertyCellType::kConstant || | |
6601 cell_type == PropertyCellType::kUndefined) { | |
6602 Handle<Object> constant(cell->value(), isolate()); | 6567 Handle<Object> constant(cell->value(), isolate()); |
6603 if (value->IsConstant()) { | 6568 if (value->IsConstant()) { |
6604 HConstant* c_value = HConstant::cast(value); | 6569 HConstant* c_value = HConstant::cast(value); |
6605 if (!constant.is_identical_to(c_value->handle(isolate()))) { | 6570 if (!constant.is_identical_to(c_value->handle(isolate()))) { |
6606 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, | 6571 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, |
6607 Deoptimizer::EAGER); | 6572 Deoptimizer::EAGER); |
6608 } | 6573 } |
6609 } else { | 6574 } else { |
6610 HValue* c_constant = Add<HConstant>(constant); | 6575 HValue* c_constant = Add<HConstant>(constant); |
6611 IfBuilder builder(this); | 6576 IfBuilder builder(this); |
6612 if (constant->IsNumber()) { | 6577 if (constant->IsNumber()) { |
6613 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); | 6578 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); |
6614 } else { | 6579 } else { |
6615 builder.If<HCompareObjectEqAndBranch>(value, c_constant); | 6580 builder.If<HCompareObjectEqAndBranch>(value, c_constant); |
6616 } | 6581 } |
6617 builder.Then(); | 6582 builder.Then(); |
6618 builder.Else(); | 6583 builder.Else(); |
6619 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, | 6584 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, |
6620 Deoptimizer::EAGER); | 6585 Deoptimizer::EAGER); |
6621 builder.End(); | 6586 builder.End(); |
6622 } | 6587 } |
6623 } | 6588 } |
6624 HConstant* cell_constant = Add<HConstant>(cell); | 6589 HConstant* cell_constant = Add<HConstant>(cell); |
6625 auto access = HObjectAccess::ForPropertyCellValue(); | 6590 HInstruction* instr = Add<HStoreNamedField>( |
6626 if (cell_type == PropertyCellType::kConstantType) { | 6591 cell_constant, HObjectAccess::ForPropertyCellValue(), value); |
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); | |
6649 instr->ClearChangesFlag(kInobjectFields); | 6592 instr->ClearChangesFlag(kInobjectFields); |
6650 instr->SetChangesFlag(kGlobalVars); | 6593 instr->SetChangesFlag(kGlobalVars); |
6651 if (instr->HasObservableSideEffects()) { | 6594 if (instr->HasObservableSideEffects()) { |
6652 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6595 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6653 } | 6596 } |
6654 } else { | 6597 } else { |
6655 HValue* global_object = Add<HLoadNamedField>( | 6598 HValue* global_object = Add<HLoadNamedField>( |
6656 context(), nullptr, | 6599 context(), nullptr, |
6657 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 6600 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
6658 HStoreNamedGeneric* instr = | 6601 HStoreNamedGeneric* instr = |
(...skipping 6376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13035 if (ShouldProduceTraceOutput()) { | 12978 if (ShouldProduceTraceOutput()) { |
13036 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12979 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13037 } | 12980 } |
13038 | 12981 |
13039 #ifdef DEBUG | 12982 #ifdef DEBUG |
13040 graph_->Verify(false); // No full verify. | 12983 graph_->Verify(false); // No full verify. |
13041 #endif | 12984 #endif |
13042 } | 12985 } |
13043 | 12986 |
13044 } } // namespace v8::internal | 12987 } } // namespace v8::internal |
OLD | NEW |