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 |