Index: src/compiler/js-global-object-specialization.cc |
diff --git a/src/compiler/js-global-object-specialization.cc b/src/compiler/js-global-object-specialization.cc |
deleted file mode 100644 |
index 5f2bca9e6ad574bca4443430a5be3ceb0eedb427..0000000000000000000000000000000000000000 |
--- a/src/compiler/js-global-object-specialization.cc |
+++ /dev/null |
@@ -1,296 +0,0 @@ |
-// Copyright 2015 the V8 project authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "src/compiler/js-global-object-specialization.h" |
- |
-#include "src/compilation-dependencies.h" |
-#include "src/compiler/access-builder.h" |
-#include "src/compiler/common-operator.h" |
-#include "src/compiler/js-graph.h" |
-#include "src/compiler/js-operator.h" |
-#include "src/compiler/node-properties.h" |
-#include "src/compiler/simplified-operator.h" |
-#include "src/compiler/type-cache.h" |
-#include "src/lookup.h" |
-#include "src/objects-inl.h" |
- |
-namespace v8 { |
-namespace internal { |
-namespace compiler { |
- |
-struct JSGlobalObjectSpecialization::ScriptContextTableLookupResult { |
- Handle<Context> context; |
- bool immutable; |
- int index; |
-}; |
- |
-JSGlobalObjectSpecialization::JSGlobalObjectSpecialization( |
- Editor* editor, JSGraph* jsgraph, Handle<JSGlobalObject> global_object, |
- CompilationDependencies* dependencies) |
- : AdvancedReducer(editor), |
- jsgraph_(jsgraph), |
- global_object_(global_object), |
- dependencies_(dependencies), |
- type_cache_(TypeCache::Get()) {} |
- |
-Reduction JSGlobalObjectSpecialization::Reduce(Node* node) { |
- switch (node->opcode()) { |
- case IrOpcode::kJSLoadGlobal: |
- return ReduceJSLoadGlobal(node); |
- case IrOpcode::kJSStoreGlobal: |
- return ReduceJSStoreGlobal(node); |
- default: |
- break; |
- } |
- return NoChange(); |
-} |
- |
-namespace { |
- |
-FieldAccess ForPropertyCellValue(MachineRepresentation representation, |
- Type* type, MaybeHandle<Map> map, |
- Handle<Name> name) { |
- WriteBarrierKind kind = kFullWriteBarrier; |
- if (representation == MachineRepresentation::kTaggedSigned) { |
- kind = kNoWriteBarrier; |
- } else if (representation == MachineRepresentation::kTaggedPointer) { |
- kind = kPointerWriteBarrier; |
- } |
- MachineType r = MachineType::TypeForRepresentation(representation); |
- FieldAccess access = { |
- kTaggedBase, PropertyCell::kValueOffset, name, map, type, r, kind}; |
- return access; |
-} |
- |
-} // namespace |
- |
-Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) { |
- DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); |
- Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); |
- Node* effect = NodeProperties::GetEffectInput(node); |
- Node* control = NodeProperties::GetControlInput(node); |
- |
- // Try to lookup the name on the script context table first (lexical scoping). |
- ScriptContextTableLookupResult result; |
- if (LookupInScriptContextTable(name, &result)) { |
- if (result.context->is_the_hole(isolate(), result.index)) return NoChange(); |
- Node* context = jsgraph()->HeapConstant(result.context); |
- Node* value = effect = graph()->NewNode( |
- javascript()->LoadContext(0, result.index, result.immutable), context, |
- effect); |
- ReplaceWithValue(node, value, effect); |
- return Replace(value); |
- } |
- |
- // Lookup on the global object instead. We only deal with own data |
- // properties of the global object here (represented as PropertyCell). |
- LookupIterator it(global_object(), name, LookupIterator::OWN); |
- it.TryLookupCachedProperty(); |
- if (it.state() != LookupIterator::DATA) return NoChange(); |
- if (!it.GetHolder<JSObject>()->IsJSGlobalObject()) return NoChange(); |
- Handle<PropertyCell> property_cell = it.GetPropertyCell(); |
- PropertyDetails property_details = property_cell->property_details(); |
- Handle<Object> property_cell_value(property_cell->value(), isolate()); |
- |
- // Load from non-configurable, read-only data property on the global |
- // object can be constant-folded, even without deoptimization support. |
- if (!property_details.IsConfigurable() && property_details.IsReadOnly()) { |
- Node* value = jsgraph()->Constant(property_cell_value); |
- ReplaceWithValue(node, value); |
- return Replace(value); |
- } |
- |
- // Record a code dependency on the cell if we can benefit from the |
- // additional feedback, or the global property is configurable (i.e. |
- // can be deleted or reconfigured to an accessor property). |
- if (property_details.cell_type() != PropertyCellType::kMutable || |
- property_details.IsConfigurable()) { |
- dependencies()->AssumePropertyCell(property_cell); |
- } |
- |
- // Load from constant/undefined global property can be constant-folded. |
- if (property_details.cell_type() == PropertyCellType::kConstant || |
- property_details.cell_type() == PropertyCellType::kUndefined) { |
- Node* value = jsgraph()->Constant(property_cell_value); |
- ReplaceWithValue(node, value); |
- return Replace(value); |
- } |
- |
- // Load from constant type cell can benefit from type feedback. |
- MaybeHandle<Map> map; |
- Type* property_cell_value_type = Type::NonInternal(); |
- MachineRepresentation representation = MachineRepresentation::kTagged; |
- if (property_details.cell_type() == PropertyCellType::kConstantType) { |
- // Compute proper type based on the current value in the cell. |
- if (property_cell_value->IsSmi()) { |
- property_cell_value_type = Type::SignedSmall(); |
- representation = MachineRepresentation::kTaggedSigned; |
- } else if (property_cell_value->IsNumber()) { |
- property_cell_value_type = Type::Number(); |
- representation = MachineRepresentation::kTaggedPointer; |
- } else { |
- Handle<Map> property_cell_value_map( |
- Handle<HeapObject>::cast(property_cell_value)->map(), isolate()); |
- property_cell_value_type = Type::For(property_cell_value_map); |
- representation = MachineRepresentation::kTaggedPointer; |
- |
- // We can only use the property cell value map for map check elimination |
- // if it's stable, i.e. the HeapObject wasn't mutated without the cell |
- // state being updated. |
- if (property_cell_value_map->is_stable()) { |
- dependencies()->AssumeMapStable(property_cell_value_map); |
- map = property_cell_value_map; |
- } |
- } |
- } |
- Node* value = effect = graph()->NewNode( |
- simplified()->LoadField(ForPropertyCellValue( |
- representation, property_cell_value_type, map, name)), |
- jsgraph()->HeapConstant(property_cell), effect, control); |
- ReplaceWithValue(node, value, effect, control); |
- return Replace(value); |
-} |
- |
- |
-Reduction JSGlobalObjectSpecialization::ReduceJSStoreGlobal(Node* node) { |
- DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode()); |
- Handle<Name> name = StoreGlobalParametersOf(node->op()).name(); |
- Node* value = NodeProperties::GetValueInput(node, 0); |
- Node* effect = NodeProperties::GetEffectInput(node); |
- Node* control = NodeProperties::GetControlInput(node); |
- |
- // Try to lookup the name on the script context table first (lexical scoping). |
- ScriptContextTableLookupResult result; |
- if (LookupInScriptContextTable(name, &result)) { |
- if (result.context->is_the_hole(isolate(), result.index)) return NoChange(); |
- if (result.immutable) return NoChange(); |
- Node* context = jsgraph()->HeapConstant(result.context); |
- effect = graph()->NewNode(javascript()->StoreContext(0, result.index), |
- value, context, effect, control); |
- ReplaceWithValue(node, value, effect, control); |
- return Replace(value); |
- } |
- |
- // Lookup on the global object instead. We only deal with own data |
- // properties of the global object here (represented as PropertyCell). |
- LookupIterator it(global_object(), name, LookupIterator::OWN); |
- if (it.state() != LookupIterator::DATA) return NoChange(); |
- if (!it.GetHolder<JSObject>()->IsJSGlobalObject()) return NoChange(); |
- Handle<PropertyCell> property_cell = it.GetPropertyCell(); |
- PropertyDetails property_details = property_cell->property_details(); |
- Handle<Object> property_cell_value(property_cell->value(), isolate()); |
- |
- // Don't even bother trying to lower stores to read-only data properties. |
- if (property_details.IsReadOnly()) return NoChange(); |
- switch (property_details.cell_type()) { |
- case PropertyCellType::kUndefined: { |
- return NoChange(); |
- } |
- case PropertyCellType::kConstant: { |
- // Record a code dependency on the cell, and just deoptimize if the new |
- // value doesn't match the previous value stored inside the cell. |
- dependencies()->AssumePropertyCell(property_cell); |
- Node* check = graph()->NewNode(simplified()->ReferenceEqual(), value, |
- jsgraph()->Constant(property_cell_value)); |
- effect = |
- graph()->NewNode(simplified()->CheckIf(), check, effect, control); |
- break; |
- } |
- case PropertyCellType::kConstantType: { |
- // Record a code dependency on the cell, and just deoptimize if the new |
- // values' type doesn't match the type of the previous value in the cell. |
- dependencies()->AssumePropertyCell(property_cell); |
- Type* property_cell_value_type; |
- MachineRepresentation representation = MachineRepresentation::kTagged; |
- if (property_cell_value->IsHeapObject()) { |
- // We cannot do anything if the {property_cell_value}s map is no |
- // longer stable. |
- Handle<Map> property_cell_value_map( |
- Handle<HeapObject>::cast(property_cell_value)->map(), isolate()); |
- if (!property_cell_value_map->is_stable()) return NoChange(); |
- dependencies()->AssumeMapStable(property_cell_value_map); |
- |
- // Check that the {value} is a HeapObject. |
- value = effect = graph()->NewNode(simplified()->CheckHeapObject(), |
- value, effect, control); |
- |
- // Check {value} map agains the {property_cell} map. |
- effect = |
- graph()->NewNode(simplified()->CheckMaps( |
- CheckMapsFlag::kNone, |
- ZoneHandleSet<Map>(property_cell_value_map)), |
- value, effect, control); |
- property_cell_value_type = Type::OtherInternal(); |
- representation = MachineRepresentation::kTaggedPointer; |
- } else { |
- // Check that the {value} is a Smi. |
- value = effect = |
- graph()->NewNode(simplified()->CheckSmi(), value, effect, control); |
- property_cell_value_type = Type::SignedSmall(); |
- representation = MachineRepresentation::kTaggedSigned; |
- } |
- effect = graph()->NewNode(simplified()->StoreField(ForPropertyCellValue( |
- representation, property_cell_value_type, |
- MaybeHandle<Map>(), name)), |
- jsgraph()->HeapConstant(property_cell), value, |
- effect, control); |
- break; |
- } |
- case PropertyCellType::kMutable: { |
- // Record a code dependency on the cell, and just deoptimize if the |
- // property ever becomes read-only. |
- dependencies()->AssumePropertyCell(property_cell); |
- effect = graph()->NewNode( |
- simplified()->StoreField(ForPropertyCellValue( |
- MachineRepresentation::kTagged, Type::NonInternal(), |
- MaybeHandle<Map>(), name)), |
- jsgraph()->HeapConstant(property_cell), value, effect, control); |
- break; |
- } |
- } |
- ReplaceWithValue(node, value, effect, control); |
- return Replace(value); |
-} |
- |
-bool JSGlobalObjectSpecialization::LookupInScriptContextTable( |
- Handle<Name> name, ScriptContextTableLookupResult* result) { |
- if (!name->IsString()) return false; |
- Handle<ScriptContextTable> script_context_table( |
- global_object()->native_context()->script_context_table(), isolate()); |
- ScriptContextTable::LookupResult lookup_result; |
- if (!ScriptContextTable::Lookup(script_context_table, |
- Handle<String>::cast(name), &lookup_result)) { |
- return false; |
- } |
- Handle<Context> script_context = ScriptContextTable::GetContext( |
- script_context_table, lookup_result.context_index); |
- result->context = script_context; |
- result->immutable = lookup_result.mode == CONST; |
- result->index = lookup_result.slot_index; |
- return true; |
-} |
- |
-Graph* JSGlobalObjectSpecialization::graph() const { |
- return jsgraph()->graph(); |
-} |
- |
-Isolate* JSGlobalObjectSpecialization::isolate() const { |
- return jsgraph()->isolate(); |
-} |
- |
-CommonOperatorBuilder* JSGlobalObjectSpecialization::common() const { |
- return jsgraph()->common(); |
-} |
- |
-JSOperatorBuilder* JSGlobalObjectSpecialization::javascript() const { |
- return jsgraph()->javascript(); |
-} |
- |
-SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const { |
- return jsgraph()->simplified(); |
-} |
- |
-} // namespace compiler |
-} // namespace internal |
-} // namespace v8 |