Index: src/compiler/js-native-context-specialization.cc |
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc |
index 237d372fb00ade0b8e3ac92f81fa51d673a9c83b..d6c4fa9ab5809a95f266c9def4a7e1683bbe76f0 100644 |
--- a/src/compiler/js-native-context-specialization.cc |
+++ b/src/compiler/js-native-context-specialization.cc |
@@ -8,6 +8,7 @@ |
#include "src/code-factory.h" |
#include "src/compilation-dependencies.h" |
#include "src/compiler/access-builder.h" |
+#include "src/compiler/access-info.h" |
#include "src/compiler/js-graph.h" |
#include "src/compiler/js-operator.h" |
#include "src/compiler/linkage.h" |
@@ -24,7 +25,7 @@ namespace compiler { |
JSNativeContextSpecialization::JSNativeContextSpecialization( |
Editor* editor, JSGraph* jsgraph, Flags flags, |
- Handle<Context> native_context, CompilationDependencies* dependencies, |
+ MaybeHandle<Context> native_context, CompilationDependencies* dependencies, |
Zone* zone) |
: AdvancedReducer(editor), |
jsgraph_(jsgraph), |
@@ -32,8 +33,7 @@ JSNativeContextSpecialization::JSNativeContextSpecialization( |
native_context_(native_context), |
dependencies_(dependencies), |
zone_(zone), |
- type_cache_(TypeCache::Get()), |
- access_info_factory_(dependencies, native_context, graph()->zone()) {} |
+ type_cache_(TypeCache::Get()) {} |
Reduction JSNativeContextSpecialization::Reduce(Node* node) { |
@@ -69,9 +69,15 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( |
// Not much we can do if deoptimization support is disabled. |
if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
+ // Retrieve the native context from the given {node}. |
+ Handle<Context> native_context; |
+ if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange(); |
+ |
// Compute property access infos for the receiver maps. |
+ AccessInfoFactory access_info_factory(dependencies(), native_context, |
+ graph()->zone()); |
ZoneVector<PropertyAccessInfo> access_infos(zone()); |
- if (!access_info_factory().ComputePropertyAccessInfos( |
+ if (!access_info_factory.ComputePropertyAccessInfos( |
receiver_maps, name, access_mode, &access_infos)) { |
return NoChange(); |
} |
@@ -183,7 +189,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( |
// Determine actual holder and perform prototype chain checks. |
Handle<JSObject> holder; |
if (access_info.holder().ToHandle(&holder)) { |
- AssumePrototypesStable(receiver_type, holder); |
+ AssumePrototypesStable(receiver_type, native_context, holder); |
} |
// Generate the actual property access. |
@@ -487,10 +493,16 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( |
// TODO(bmeurer): Add support for non-standard stores. |
if (store_mode != STANDARD_STORE) return NoChange(); |
+ // Retrieve the native context from the given {node}. |
+ Handle<Context> native_context; |
+ if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange(); |
+ |
// Compute element access infos for the receiver maps. |
+ AccessInfoFactory access_info_factory(dependencies(), native_context, |
+ graph()->zone()); |
ZoneVector<ElementAccessInfo> access_infos(zone()); |
- if (!access_info_factory().ComputeElementAccessInfos( |
- receiver_maps, access_mode, &access_infos)) { |
+ if (!access_info_factory.ComputeElementAccessInfos(receiver_maps, access_mode, |
+ &access_infos)) { |
return NoChange(); |
} |
@@ -613,7 +625,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( |
// not compatible with (monomorphic) keyed stores. |
Handle<JSObject> holder; |
if (access_info.holder().ToHandle(&holder)) { |
- AssumePrototypesStable(receiver_type, holder); |
+ AssumePrototypesStable(receiver_type, native_context, holder); |
} |
// Check that the {index} is actually a Number. |
@@ -667,24 +679,15 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( |
} |
// Load the length of the {receiver}. |
- Node* this_length; |
- if (receiver_is_jsarray) { |
- FieldAccess length_access = { |
- kTaggedBase, JSArray::kLengthOffset, factory()->name_string(), |
- type_cache_.kJSArrayLengthType, kMachAnyTagged}; |
- if (IsFastDoubleElementsKind(elements_kind)) { |
- length_access.type = type_cache_.kFixedDoubleArrayLengthType; |
- } else if (IsFastElementsKind(elements_kind)) { |
- length_access.type = type_cache_.kFixedArrayLengthType; |
- } |
- this_length = this_effect = |
- graph()->NewNode(simplified()->LoadField(length_access), |
- this_receiver, this_effect, this_control); |
- } else { |
- this_length = this_effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), |
- this_elements, this_effect, this_control); |
- } |
+ Node* this_length = this_effect = |
+ receiver_is_jsarray |
+ ? graph()->NewNode( |
+ simplified()->LoadField( |
+ AccessBuilder::ForJSArrayLength(elements_kind)), |
+ this_receiver, this_effect, this_control) |
+ : graph()->NewNode( |
+ simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), |
+ this_elements, this_effect, this_control); |
// Check that the {index} is in the valid range for the {receiver}. |
Node* check = graph()->NewNode(simplified()->NumberLessThan(), this_index, |
@@ -742,7 +745,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( |
if (receiver_type->NowIs(initial_holey_array_type) && |
isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
// Add a code dependency on the array protector cell. |
- AssumePrototypesStable(receiver_type, |
+ AssumePrototypesStable(receiver_type, native_context, |
isolate()->initial_object_prototype()); |
dependencies()->AssumePropertyCell(factory()->array_protector()); |
// Turn the hole into undefined. |
@@ -773,7 +776,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( |
if (receiver_type->NowIs(initial_holey_array_type) && |
isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
// Add a code dependency on the array protector cell. |
- AssumePrototypesStable(receiver_type, |
+ AssumePrototypesStable(receiver_type, native_context, |
isolate()->initial_object_prototype()); |
dependencies()->AssumePropertyCell(factory()->array_protector()); |
// Turn the hole into undefined. |
@@ -945,27 +948,19 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreProperty(Node* node) { |
void JSNativeContextSpecialization::AssumePrototypesStable( |
- Type* receiver_type, Handle<JSObject> holder) { |
+ Type* receiver_type, Handle<Context> native_context, |
+ Handle<JSObject> holder) { |
// Determine actual holder and perform prototype chain checks. |
for (auto i = receiver_type->Classes(); !i.Done(); i.Advance()) { |
Handle<Map> map = i.Current(); |
// Perform the implicit ToObject for primitives here. |
// Implemented according to ES6 section 7.3.2 GetV (V, P). |
Handle<JSFunction> constructor; |
- if (Map::GetConstructorFunction(map, native_context()) |
+ if (Map::GetConstructorFunction(map, native_context) |
.ToHandle(&constructor)) { |
map = handle(constructor->initial_map(), isolate()); |
} |
- for (PrototypeIterator j(map); !j.IsAtEnd(); j.Advance()) { |
- // Check that the {prototype} still has the same map. All prototype |
- // maps are guaranteed to be stable, so it's sufficient to add a |
- // stability dependency here. |
- Handle<JSReceiver> const prototype = |
- PrototypeIterator::GetCurrent<JSReceiver>(j); |
- dependencies()->AssumeMapStable(handle(prototype->map(), isolate())); |
- // Stop once we get to the holder. |
- if (prototype.is_identical_to(holder)) break; |
- } |
+ dependencies()->AssumePrototypeMapsStable(map, holder); |
} |
} |
@@ -982,6 +977,14 @@ void JSNativeContextSpecialization::MarkAsDeferred(Node* if_projection) { |
} |
+MaybeHandle<Context> JSNativeContextSpecialization::GetNativeContext( |
+ Node* node) { |
+ Node* const context = NodeProperties::GetContextInput(node); |
+ return NodeProperties::GetSpecializationNativeContext(context, |
+ native_context()); |
+} |
+ |
+ |
Graph* JSNativeContextSpecialization::graph() const { |
return jsgraph()->graph(); |
} |