Commit 7f5a2d9e authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[turbofan] Make global variable loads and stores explicit.

This is a precursor to using specialized LoadIC and StoreIC stubs for
global variable access. It also removes the need to keep track of the
global object in the type system, hence freeing up one bit.

R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/1205473004

Cr-Commit-Position: refs/heads/master@{#29231}
parent 78e9a2df
...@@ -3233,7 +3233,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, ...@@ -3233,7 +3233,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
// Global var, const, or let variable. // Global var, const, or let variable.
Node* global = BuildLoadGlobalObject(); Node* global = BuildLoadGlobalObject();
Handle<Name> name = variable->name(); Handle<Name> name = variable->name();
Node* value = BuildNamedLoad(global, name, feedback, contextual_mode); Node* value = BuildGlobalLoad(global, name, feedback, contextual_mode);
states.AddToNode(value, bailout_id, combine); states.AddToNode(value, bailout_id, combine);
return value; return value;
} }
...@@ -3367,7 +3367,7 @@ Node* AstGraphBuilder::BuildVariableAssignment( ...@@ -3367,7 +3367,7 @@ Node* AstGraphBuilder::BuildVariableAssignment(
// Global var, const, or let variable. // Global var, const, or let variable.
Node* global = BuildLoadGlobalObject(); Node* global = BuildLoadGlobalObject();
Handle<Name> name = variable->name(); Handle<Name> name = variable->name();
Node* store = BuildNamedStore(global, name, value, feedback, Node* store = BuildGlobalStore(global, name, value, feedback,
TypeFeedbackId::None()); TypeFeedbackId::None());
states.AddToNode(store, bailout_id, combine); states.AddToNode(store, bailout_id, combine);
return store; return store;
...@@ -3491,10 +3491,8 @@ Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key, ...@@ -3491,10 +3491,8 @@ Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name, Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
const VectorSlotPair& feedback, const VectorSlotPair& feedback) {
ContextualMode mode) { const Operator* op = javascript()->LoadNamed(MakeUnique(name), feedback);
const Operator* op =
javascript()->LoadNamed(MakeUnique(name), feedback, mode);
Node* node = NewNode(op, object, BuildLoadFeedbackVector()); Node* node = NewNode(op, object, BuildLoadFeedbackVector());
return Record(js_type_feedback_, node, feedback.slot()); return Record(js_type_feedback_, node, feedback.slot());
} }
...@@ -3571,6 +3569,30 @@ Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object, ...@@ -3571,6 +3569,30 @@ Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object,
} }
Node* AstGraphBuilder::BuildGlobalLoad(Node* object, Handle<Name> name,
const VectorSlotPair& feedback,
ContextualMode mode) {
const Operator* op =
javascript()->LoadGlobal(MakeUnique(name), feedback, mode);
Node* node = NewNode(op, object, BuildLoadFeedbackVector());
return Record(js_type_feedback_, node, feedback.slot());
}
Node* AstGraphBuilder::BuildGlobalStore(Node* object, Handle<Name> name,
Node* value,
const VectorSlotPair& feedback,
TypeFeedbackId id) {
const Operator* op =
javascript()->StoreGlobal(language_mode(), MakeUnique(name), feedback);
Node* node = NewNode(op, object, value, BuildLoadFeedbackVector());
if (FLAG_vector_stores) {
return Record(js_type_feedback_, node, feedback.slot());
}
return Record(js_type_feedback_, node, id);
}
Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
jsgraph()->IntPtrConstant(offset - kHeapObjectTag)); jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
......
...@@ -290,11 +290,10 @@ class AstGraphBuilder : public AstVisitor { ...@@ -290,11 +290,10 @@ class AstGraphBuilder : public AstVisitor {
Node* BuildKeyedLoad(Node* receiver, Node* key, Node* BuildKeyedLoad(Node* receiver, Node* key,
const VectorSlotPair& feedback); const VectorSlotPair& feedback);
Node* BuildNamedLoad(Node* receiver, Handle<Name> name, Node* BuildNamedLoad(Node* receiver, Handle<Name> name,
const VectorSlotPair& feedback, const VectorSlotPair& feedback);
ContextualMode mode = NOT_CONTEXTUAL);
Node* BuildKeyedStore(Node* receiver, Node* key, Node* value, Node* BuildKeyedStore(Node* receiver, Node* key, Node* value,
const VectorSlotPair& feedback, TypeFeedbackId id); const VectorSlotPair& feedback, TypeFeedbackId id);
Node* BuildNamedStore(Node* receiver, Handle<Name>, Node* value, Node* BuildNamedStore(Node* receiver, Handle<Name> name, Node* value,
const VectorSlotPair& feedback, TypeFeedbackId id); const VectorSlotPair& feedback, TypeFeedbackId id);
// Builders for super property loads and stores. // Builders for super property loads and stores.
...@@ -307,6 +306,12 @@ class AstGraphBuilder : public AstVisitor { ...@@ -307,6 +306,12 @@ class AstGraphBuilder : public AstVisitor {
Node* BuildKeyedSuperLoad(Node* receiver, Node* home_object, Node* key, Node* BuildKeyedSuperLoad(Node* receiver, Node* home_object, Node* key,
const VectorSlotPair& feedback); const VectorSlotPair& feedback);
// Builders for global variable loads and stores.
Node* BuildGlobalLoad(Node* global, Handle<Name> name,
const VectorSlotPair& feedback, ContextualMode mode);
Node* BuildGlobalStore(Node* global, Handle<Name> name, Node* value,
const VectorSlotPair& feedback, TypeFeedbackId id);
// Builders for accessing the function context. // Builders for accessing the function context.
Node* BuildLoadBuiltinsObject(); Node* BuildLoadBuiltinsObject();
Node* BuildLoadGlobalObject(); Node* BuildLoadGlobalObject();
......
...@@ -332,6 +332,17 @@ void JSGenericLowering::LowerJSLoadNamed(Node* node) { ...@@ -332,6 +332,17 @@ void JSGenericLowering::LowerJSLoadNamed(Node* node) {
} }
void JSGenericLowering::LowerJSLoadGlobal(Node* node) {
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const LoadNamedParameters& p = LoadGlobalParametersOf(node->op());
Callable callable = CodeFactory::LoadICInOptimizedCode(
isolate(), p.contextual_mode(), UNINITIALIZED);
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
ReplaceWithStubCall(node, callable, flags);
}
void JSGenericLowering::LowerJSStoreProperty(Node* node) { void JSGenericLowering::LowerJSStoreProperty(Node* node) {
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const StorePropertyParameters& p = StorePropertyParametersOf(node->op()); const StorePropertyParameters& p = StorePropertyParametersOf(node->op());
...@@ -365,6 +376,22 @@ void JSGenericLowering::LowerJSStoreNamed(Node* node) { ...@@ -365,6 +376,22 @@ void JSGenericLowering::LowerJSStoreNamed(Node* node) {
} }
void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const StoreNamedParameters& p = StoreGlobalParametersOf(node->op());
Callable callable = CodeFactory::StoreIC(isolate(), p.language_mode());
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
if (FLAG_vector_stores) {
DCHECK(p.feedback().index() != -1);
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
} else {
node->RemoveInput(3);
}
ReplaceWithStubCall(node, callable,
CallDescriptor::kPatchableCallSite | flags);
}
void JSGenericLowering::LowerJSDeleteProperty(Node* node) { void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
LanguageMode language_mode = OpParameter<LanguageMode>(node); LanguageMode language_mode = OpParameter<LanguageMode>(node);
ReplaceWithBuiltinCall(node, Builtins::DELETE, 3); ReplaceWithBuiltinCall(node, Builtins::DELETE, 3);
......
...@@ -249,6 +249,12 @@ const LoadNamedParameters& LoadNamedParametersOf(const Operator* op) { ...@@ -249,6 +249,12 @@ const LoadNamedParameters& LoadNamedParametersOf(const Operator* op) {
} }
const LoadNamedParameters& LoadGlobalParametersOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSLoadGlobal, op->opcode());
return OpParameter<LoadNamedParameters>(op);
}
bool operator==(StoreNamedParameters const& lhs, bool operator==(StoreNamedParameters const& lhs,
StoreNamedParameters const& rhs) { StoreNamedParameters const& rhs) {
return lhs.language_mode() == rhs.language_mode() && return lhs.language_mode() == rhs.language_mode() &&
...@@ -278,6 +284,12 @@ const StoreNamedParameters& StoreNamedParametersOf(const Operator* op) { ...@@ -278,6 +284,12 @@ const StoreNamedParameters& StoreNamedParametersOf(const Operator* op) {
} }
const StoreNamedParameters& StoreGlobalParametersOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode());
return OpParameter<StoreNamedParameters>(op);
}
bool operator==(StorePropertyParameters const& lhs, bool operator==(StorePropertyParameters const& lhs,
StorePropertyParameters const& rhs) { StorePropertyParameters const& rhs) {
return lhs.language_mode() == rhs.language_mode() && return lhs.language_mode() == rhs.language_mode() &&
...@@ -490,9 +502,8 @@ const Operator* JSOperatorBuilder::CallConstruct(int arguments) { ...@@ -490,9 +502,8 @@ const Operator* JSOperatorBuilder::CallConstruct(int arguments) {
const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name, const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback, const VectorSlotPair& feedback) {
ContextualMode contextual_mode) { LoadNamedParameters parameters(name, feedback, NOT_CONTEXTUAL);
LoadNamedParameters parameters(name, feedback, contextual_mode);
return new (zone()) Operator1<LoadNamedParameters>( // -- return new (zone()) Operator1<LoadNamedParameters>( // --
IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
"JSLoadNamed", // name "JSLoadNamed", // name
...@@ -544,6 +555,30 @@ const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) { ...@@ -544,6 +555,30 @@ const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) {
} }
const Operator* JSOperatorBuilder::LoadGlobal(const Unique<Name>& name,
const VectorSlotPair& feedback,
ContextualMode contextual_mode) {
LoadNamedParameters parameters(name, feedback, contextual_mode);
return new (zone()) Operator1<LoadNamedParameters>( // --
IrOpcode::kJSLoadGlobal, Operator::kNoProperties, // opcode
"JSLoadGlobal", // name
2, 1, 1, 1, 1, 2, // counts
parameters); // parameter
}
const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode,
const Unique<Name>& name,
const VectorSlotPair& feedback) {
StoreNamedParameters parameters(language_mode, feedback, name);
return new (zone()) Operator1<StoreNamedParameters>( // --
IrOpcode::kJSStoreGlobal, Operator::kNoProperties, // opcode
"JSStoreGlobal", // name
3, 1, 1, 0, 1, 2, // counts
parameters); // parameter
}
const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index, const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index,
bool immutable) { bool immutable) {
ContextAccess access(depth, index, immutable); ContextAccess access(depth, index, immutable);
......
...@@ -227,7 +227,7 @@ DynamicContextAccess const& DynamicContextAccessOf(Operator const*); ...@@ -227,7 +227,7 @@ DynamicContextAccess const& DynamicContextAccessOf(Operator const*);
// Defines the property being loaded from an object by a named load. This is // Defines the property being loaded from an object by a named load. This is
// used as a parameter by JSLoadNamed operators. // used as a parameter by JSLoadNamed and JSLoadGlobal operators.
class LoadNamedParameters final { class LoadNamedParameters final {
public: public:
LoadNamedParameters(const Unique<Name>& name, const VectorSlotPair& feedback, LoadNamedParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
...@@ -254,6 +254,8 @@ std::ostream& operator<<(std::ostream&, LoadNamedParameters const&); ...@@ -254,6 +254,8 @@ std::ostream& operator<<(std::ostream&, LoadNamedParameters const&);
const LoadNamedParameters& LoadNamedParametersOf(const Operator* op); const LoadNamedParameters& LoadNamedParametersOf(const Operator* op);
const LoadNamedParameters& LoadGlobalParametersOf(const Operator* op);
// Defines the property being loaded from an object. This is // Defines the property being loaded from an object. This is
// used as a parameter by JSLoadProperty operators. // used as a parameter by JSLoadProperty operators.
...@@ -279,7 +281,7 @@ const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op); ...@@ -279,7 +281,7 @@ const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op);
// Defines the property being stored to an object by a named store. This is // Defines the property being stored to an object by a named store. This is
// used as a parameter by JSStoreNamed operators. // used as a parameter by JSStoreNamed and JSStoreGlobal operators.
class StoreNamedParameters final { class StoreNamedParameters final {
public: public:
StoreNamedParameters(LanguageMode language_mode, StoreNamedParameters(LanguageMode language_mode,
...@@ -305,6 +307,8 @@ std::ostream& operator<<(std::ostream&, StoreNamedParameters const&); ...@@ -305,6 +307,8 @@ std::ostream& operator<<(std::ostream&, StoreNamedParameters const&);
const StoreNamedParameters& StoreNamedParametersOf(const Operator* op); const StoreNamedParameters& StoreNamedParametersOf(const Operator* op);
const StoreNamedParameters& StoreGlobalParametersOf(const Operator* op);
// Defines the property being stored to an object. This is used as a parameter // Defines the property being stored to an object. This is used as a parameter
// by JSStoreProperty operators. // by JSStoreProperty operators.
...@@ -408,8 +412,7 @@ class JSOperatorBuilder final : public ZoneObject { ...@@ -408,8 +412,7 @@ class JSOperatorBuilder final : public ZoneObject {
const Operator* LoadProperty(const VectorSlotPair& feedback); const Operator* LoadProperty(const VectorSlotPair& feedback);
const Operator* LoadNamed(const Unique<Name>& name, const Operator* LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback, const VectorSlotPair& feedback);
ContextualMode contextual_mode = NOT_CONTEXTUAL);
const Operator* StoreProperty(LanguageMode language_mode, const Operator* StoreProperty(LanguageMode language_mode,
const VectorSlotPair& feedback); const VectorSlotPair& feedback);
...@@ -421,6 +424,13 @@ class JSOperatorBuilder final : public ZoneObject { ...@@ -421,6 +424,13 @@ class JSOperatorBuilder final : public ZoneObject {
const Operator* HasProperty(); const Operator* HasProperty();
const Operator* LoadGlobal(const Unique<Name>& name,
const VectorSlotPair& feedback,
ContextualMode contextual_mode = NOT_CONTEXTUAL);
const Operator* StoreGlobal(LanguageMode language_mode,
const Unique<Name>& name,
const VectorSlotPair& feedback);
const Operator* LoadContext(size_t depth, size_t index, bool immutable); const Operator* LoadContext(size_t depth, size_t index, bool immutable);
const Operator* StoreContext(size_t depth, size_t index); const Operator* StoreContext(size_t depth, size_t index);
......
...@@ -52,6 +52,8 @@ Reduction JSTypeFeedbackSpecializer::Reduce(Node* node) { ...@@ -52,6 +52,8 @@ Reduction JSTypeFeedbackSpecializer::Reduce(Node* node) {
return ReduceJSLoadProperty(node); return ReduceJSLoadProperty(node);
case IrOpcode::kJSLoadNamed: case IrOpcode::kJSLoadNamed:
return ReduceJSLoadNamed(node); return ReduceJSLoadNamed(node);
case IrOpcode::kJSLoadGlobal:
return ReduceJSLoadGlobal(node);
case IrOpcode::kJSStoreNamed: case IrOpcode::kJSStoreNamed:
return ReduceJSStoreNamed(node); return ReduceJSStoreNamed(node);
case IrOpcode::kJSStoreProperty: case IrOpcode::kJSStoreProperty:
...@@ -137,19 +139,8 @@ static bool GetInObjectFieldAccess(LoadOrStore mode, Handle<Map> map, ...@@ -137,19 +139,8 @@ static bool GetInObjectFieldAccess(LoadOrStore mode, Handle<Map> map,
} }
static bool IsGlobalObject(Node* node) {
return NodeProperties::IsTyped(node) &&
NodeProperties::GetBounds(node).upper->Is(Type::GlobalObject());
}
Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) {
DCHECK(node->opcode() == IrOpcode::kJSLoadNamed); DCHECK(node->opcode() == IrOpcode::kJSLoadNamed);
Node* receiver = node->InputAt(0);
if (IsGlobalObject(receiver)) {
return ReduceJSLoadNamedForGlobalVariable(node);
}
if (mode() != kDeoptimizationEnabled) return NoChange(); if (mode() != kDeoptimizationEnabled) return NoChange();
Node* frame_state_before = GetFrameStateBefore(node); Node* frame_state_before = GetFrameStateBefore(node);
if (frame_state_before == nullptr) return NoChange(); if (frame_state_before == nullptr) return NoChange();
...@@ -166,6 +157,7 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { ...@@ -166,6 +157,7 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) {
} }
oracle()->PropertyReceiverTypes(slot, name, &maps); oracle()->PropertyReceiverTypes(slot, name, &maps);
Node* receiver = node->InputAt(0);
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism
...@@ -196,10 +188,10 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { ...@@ -196,10 +188,10 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) {
} }
Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamedForGlobalVariable( Reduction JSTypeFeedbackSpecializer::ReduceJSLoadGlobal(Node* node) {
Node* node) { DCHECK(node->opcode() == IrOpcode::kJSLoadGlobal);
Handle<String> name = Handle<String> name =
Handle<String>::cast(LoadNamedParametersOf(node->op()).name().handle()); Handle<String>::cast(LoadGlobalParametersOf(node->op()).name().handle());
// Try to optimize loads from the global object. // Try to optimize loads from the global object.
Handle<Object> constant_value = Handle<Object> constant_value =
jsgraph()->isolate()->factory()->GlobalConstantFor(name); jsgraph()->isolate()->factory()->GlobalConstantFor(name);
......
...@@ -84,8 +84,8 @@ class JSTypeFeedbackSpecializer : public AdvancedReducer { ...@@ -84,8 +84,8 @@ class JSTypeFeedbackSpecializer : public AdvancedReducer {
Reduction Reduce(Node* node) override; Reduction Reduce(Node* node) override;
// Visible for unit testing. // Visible for unit testing.
Reduction ReduceJSLoadGlobal(Node* node);
Reduction ReduceJSLoadNamed(Node* node); Reduction ReduceJSLoadNamed(Node* node);
Reduction ReduceJSLoadNamedForGlobalVariable(Node* node);
Reduction ReduceJSLoadProperty(Node* node); Reduction ReduceJSLoadProperty(Node* node);
Reduction ReduceJSStoreNamed(Node* node); Reduction ReduceJSStoreNamed(Node* node);
Reduction ReduceJSStoreProperty(Node* node); Reduction ReduceJSStoreProperty(Node* node);
......
...@@ -801,19 +801,15 @@ Reduction JSTypedLowering::ReduceJSToString(Node* node) { ...@@ -801,19 +801,15 @@ Reduction JSTypedLowering::ReduceJSToString(Node* node) {
} }
Reduction JSTypedLowering::ReduceJSLoadNamed(Node* node) { Reduction JSTypedLowering::ReduceJSLoadGlobal(Node* node) {
Node* object = NodeProperties::GetValueInput(node, 0);
Type* object_type = NodeProperties::GetBounds(object).upper;
if (object_type->Is(Type::GlobalObject())) {
// Optimize global constants like "undefined", "Infinity", and "NaN". // Optimize global constants like "undefined", "Infinity", and "NaN".
Handle<Name> name = LoadNamedParametersOf(node->op()).name().handle(); Handle<Name> name = LoadGlobalParametersOf(node->op()).name().handle();
Handle<Object> constant_value = factory()->GlobalConstantFor(name); Handle<Object> constant_value = factory()->GlobalConstantFor(name);
if (!constant_value.is_null()) { if (!constant_value.is_null()) {
Node* constant = jsgraph()->Constant(constant_value); Node* constant = jsgraph()->Constant(constant_value);
ReplaceWithValue(node, constant); ReplaceWithValue(node, constant);
return Replace(constant); return Replace(constant);
} }
}
return NoChange(); return NoChange();
} }
...@@ -1023,7 +1019,7 @@ Reduction JSTypedLowering::ReduceJSLoadDynamicGlobal(Node* node) { ...@@ -1023,7 +1019,7 @@ Reduction JSTypedLowering::ReduceJSLoadDynamicGlobal(Node* node) {
javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true), context, javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true), context,
context, effect); context, effect);
Node* fast = graph()->NewNode( Node* fast = graph()->NewNode(
javascript()->LoadNamed(name, access.feedback(), access.mode()), global, javascript()->LoadGlobal(name, access.feedback(), access.mode()), global,
vector, context, state1, state2, global, check_true); vector, context, state1, state2, global, check_true);
// Slow case, because variable potentially shadowed. Perform dynamic lookup. // Slow case, because variable potentially shadowed. Perform dynamic lookup.
...@@ -1639,8 +1635,8 @@ Reduction JSTypedLowering::Reduce(Node* node) { ...@@ -1639,8 +1635,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceJSToNumber(node); return ReduceJSToNumber(node);
case IrOpcode::kJSToString: case IrOpcode::kJSToString:
return ReduceJSToString(node); return ReduceJSToString(node);
case IrOpcode::kJSLoadNamed: case IrOpcode::kJSLoadGlobal:
return ReduceJSLoadNamed(node); return ReduceJSLoadGlobal(node);
case IrOpcode::kJSLoadProperty: case IrOpcode::kJSLoadProperty:
return ReduceJSLoadProperty(node); return ReduceJSLoadProperty(node);
case IrOpcode::kJSStoreProperty: case IrOpcode::kJSStoreProperty:
......
...@@ -41,7 +41,7 @@ class JSTypedLowering final : public AdvancedReducer { ...@@ -41,7 +41,7 @@ class JSTypedLowering final : public AdvancedReducer {
Reduction ReduceJSBitwiseOr(Node* node); Reduction ReduceJSBitwiseOr(Node* node);
Reduction ReduceJSMultiply(Node* node); Reduction ReduceJSMultiply(Node* node);
Reduction ReduceJSComparison(Node* node); Reduction ReduceJSComparison(Node* node);
Reduction ReduceJSLoadNamed(Node* node); Reduction ReduceJSLoadGlobal(Node* node);
Reduction ReduceJSLoadProperty(Node* node); Reduction ReduceJSLoadProperty(Node* node);
Reduction ReduceJSStoreProperty(Node* node); Reduction ReduceJSStoreProperty(Node* node);
Reduction ReduceJSLoadContext(Node* node); Reduction ReduceJSLoadContext(Node* node);
......
...@@ -114,8 +114,10 @@ ...@@ -114,8 +114,10 @@
V(JSCreateLiteralObject) \ V(JSCreateLiteralObject) \
V(JSLoadProperty) \ V(JSLoadProperty) \
V(JSLoadNamed) \ V(JSLoadNamed) \
V(JSLoadGlobal) \
V(JSStoreProperty) \ V(JSStoreProperty) \
V(JSStoreNamed) \ V(JSStoreNamed) \
V(JSStoreGlobal) \
V(JSDeleteProperty) \ V(JSDeleteProperty) \
V(JSHasProperty) \ V(JSHasProperty) \
V(JSInstanceOf) V(JSInstanceOf)
......
...@@ -71,6 +71,8 @@ int OperatorProperties::GetFrameStateInputCount(const Operator* op) { ...@@ -71,6 +71,8 @@ int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
case IrOpcode::kJSStoreNamed: case IrOpcode::kJSStoreNamed:
case IrOpcode::kJSLoadProperty: case IrOpcode::kJSLoadProperty:
case IrOpcode::kJSStoreProperty: case IrOpcode::kJSStoreProperty:
case IrOpcode::kJSLoadGlobal:
case IrOpcode::kJSStoreGlobal:
case IrOpcode::kJSLoadDynamicGlobal: case IrOpcode::kJSLoadDynamicGlobal:
return 2; return 2;
......
...@@ -1338,6 +1338,11 @@ Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { ...@@ -1338,6 +1338,11 @@ Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) {
} }
Bounds Typer::Visitor::TypeJSLoadGlobal(Node* node) {
return Bounds::Unbounded(zone());
}
// Returns a somewhat larger range if we previously assigned // Returns a somewhat larger range if we previously assigned
// a (smaller) range to this node. This is used to speed up // a (smaller) range to this node. This is used to speed up
// the fixpoint calculation in case there appears to be a loop // the fixpoint calculation in case there appears to be a loop
...@@ -1431,6 +1436,12 @@ Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) { ...@@ -1431,6 +1436,12 @@ Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) {
} }
Bounds Typer::Visitor::TypeJSStoreGlobal(Node* node) {
UNREACHABLE();
return Bounds();
}
Bounds Typer::Visitor::TypeJSDeleteProperty(Node* node) { Bounds Typer::Visitor::TypeJSDeleteProperty(Node* node) {
return Bounds(Type::None(zone()), Type::Boolean(zone())); return Bounds(Type::None(zone()), Type::Boolean(zone()));
} }
...@@ -1453,12 +1464,9 @@ Bounds Typer::Visitor::TypeJSLoadContext(Node* node) { ...@@ -1453,12 +1464,9 @@ Bounds Typer::Visitor::TypeJSLoadContext(Node* node) {
ContextAccess access = OpParameter<ContextAccess>(node); ContextAccess access = OpParameter<ContextAccess>(node);
Bounds outer = Operand(node, 0); Bounds outer = Operand(node, 0);
Type* context_type = outer.upper; Type* context_type = outer.upper;
Type* upper = (access.index() == Context::GLOBAL_OBJECT_INDEX)
? Type::GlobalObject()
: Type::Any();
if (context_type->Is(Type::None())) { if (context_type->Is(Type::None())) {
// Upper bound of context is not yet known. // Upper bound of context is not yet known.
return Bounds(Type::None(), upper); return Bounds(Type::None(), Type::Any());
} }
DCHECK(context_type->Maybe(Type::Internal())); DCHECK(context_type->Maybe(Type::Internal()));
...@@ -1488,7 +1496,7 @@ Bounds Typer::Visitor::TypeJSLoadContext(Node* node) { ...@@ -1488,7 +1496,7 @@ Bounds Typer::Visitor::TypeJSLoadContext(Node* node) {
handle(context.ToHandleChecked()->get(static_cast<int>(access.index())), handle(context.ToHandleChecked()->get(static_cast<int>(access.index())),
isolate())); isolate()));
} }
return Bounds(lower, upper); return Bounds(lower, Type::Any());
} }
......
...@@ -521,11 +521,13 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -521,11 +521,13 @@ void Verifier::Visitor::Check(Node* node) {
break; break;
case IrOpcode::kJSLoadProperty: case IrOpcode::kJSLoadProperty:
case IrOpcode::kJSLoadNamed: case IrOpcode::kJSLoadNamed:
case IrOpcode::kJSLoadGlobal:
// Type can be anything. // Type can be anything.
CheckUpperIs(node, Type::Any()); CheckUpperIs(node, Type::Any());
break; break;
case IrOpcode::kJSStoreProperty: case IrOpcode::kJSStoreProperty:
case IrOpcode::kJSStoreNamed: case IrOpcode::kJSStoreNamed:
case IrOpcode::kJSStoreGlobal:
// Type is empty. // Type is empty.
CheckNotTyped(node); CheckNotTyped(node);
break; break;
......
...@@ -235,6 +235,7 @@ TypeImpl<Config>::BitsetType::Lub(i::Map* map) { ...@@ -235,6 +235,7 @@ TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
case JS_GENERATOR_OBJECT_TYPE: case JS_GENERATOR_OBJECT_TYPE:
case JS_MODULE_TYPE: case JS_MODULE_TYPE:
case JS_BUILTINS_OBJECT_TYPE: case JS_BUILTINS_OBJECT_TYPE:
case JS_GLOBAL_OBJECT_TYPE:
case JS_GLOBAL_PROXY_TYPE: case JS_GLOBAL_PROXY_TYPE:
case JS_ARRAY_BUFFER_TYPE: case JS_ARRAY_BUFFER_TYPE:
case JS_ARRAY_TYPE: case JS_ARRAY_TYPE:
...@@ -248,8 +249,6 @@ TypeImpl<Config>::BitsetType::Lub(i::Map* map) { ...@@ -248,8 +249,6 @@ TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
case JS_WEAK_SET_TYPE: case JS_WEAK_SET_TYPE:
if (map->is_undetectable()) return kUndetectable; if (map->is_undetectable()) return kUndetectable;
return kOtherObject; return kOtherObject;
case JS_GLOBAL_OBJECT_TYPE:
return kGlobalObject;
case JS_FUNCTION_TYPE: case JS_FUNCTION_TYPE:
return kOtherObject; // TODO(rossberg): there should be a Function type. return kOtherObject; // TODO(rossberg): there should be a Function type.
case JS_REGEXP_TYPE: case JS_REGEXP_TYPE:
......
...@@ -208,7 +208,7 @@ namespace internal { ...@@ -208,7 +208,7 @@ namespace internal {
V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \ V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \
V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \ V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \
V(Undetectable, 1u << 15 | REPRESENTATION(kTaggedPointer)) \ V(Undetectable, 1u << 15 | REPRESENTATION(kTaggedPointer)) \
V(GlobalObject, 1u << 16 | REPRESENTATION(kTaggedPointer)) \ /* Unused semantic bit 1u << 16 in case you are looking for a bit. */ \
V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \ V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \
V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \ V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \
V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \ V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \
...@@ -232,10 +232,9 @@ namespace internal { ...@@ -232,10 +232,9 @@ namespace internal {
V(NumberOrUndefined, kNumber | kUndefined) \ V(NumberOrUndefined, kNumber | kUndefined) \
V(PlainPrimitive, kNumberOrString | kBoolean | kNullOrUndefined) \ V(PlainPrimitive, kNumberOrString | kBoolean | kNullOrUndefined) \
V(Primitive, kSymbol | kPlainPrimitive) \ V(Primitive, kSymbol | kPlainPrimitive) \
V(DetectableObject, kGlobalObject | kOtherObject) \ V(DetectableReceiver, kOtherObject | kProxy) \
V(DetectableReceiver, kDetectableObject | kProxy) \
V(Detectable, kDetectableReceiver | kNumber | kName) \ V(Detectable, kDetectableReceiver | kNumber | kName) \
V(Object, kDetectableObject | kUndetectable) \ V(Object, kOtherObject | kUndetectable) \
V(Receiver, kObject | kProxy) \ V(Receiver, kObject | kProxy) \
V(ReceiverOrUndefined, kReceiver | kUndefined) \ V(ReceiverOrUndefined, kReceiver | kUndefined) \
V(StringOrReceiver, kString | kReceiver) \ V(StringOrReceiver, kString | kReceiver) \
......
...@@ -1020,15 +1020,10 @@ struct Tests : Rep { ...@@ -1020,15 +1020,10 @@ struct Tests : Rep {
CheckSub(T.Proxy, T.Receiver); CheckSub(T.Proxy, T.Receiver);
CheckSub(T.OtherObject, T.Object); CheckSub(T.OtherObject, T.Object);
CheckSub(T.Undetectable, T.Object); CheckSub(T.Undetectable, T.Object);
CheckSub(T.DetectableObject, T.Object); CheckSub(T.OtherObject, T.Object);
CheckSub(T.GlobalObject, T.DetectableObject);
CheckSub(T.OtherObject, T.DetectableObject);
CheckSub(T.GlobalObject, T.Object);
CheckSub(T.GlobalObject, T.Receiver);
CheckUnordered(T.Object, T.Proxy); CheckUnordered(T.Object, T.Proxy);
CheckUnordered(T.GlobalObject, T.OtherObject); CheckUnordered(T.OtherObject, T.Undetectable);
CheckUnordered(T.DetectableObject, T.Undetectable);
// Subtyping between concrete structural types // Subtyping between concrete structural types
...@@ -1350,7 +1345,6 @@ struct Tests : Rep { ...@@ -1350,7 +1345,6 @@ struct Tests : Rep {
CheckDisjoint(T.InternalizedString, T.Symbol); CheckDisjoint(T.InternalizedString, T.Symbol);
CheckOverlap(T.Object, T.Receiver); CheckOverlap(T.Object, T.Receiver);
CheckOverlap(T.OtherObject, T.Object); CheckOverlap(T.OtherObject, T.Object);
CheckOverlap(T.GlobalObject, T.Object);
CheckOverlap(T.Proxy, T.Receiver); CheckOverlap(T.Proxy, T.Receiver);
CheckDisjoint(T.Object, T.Proxy); CheckDisjoint(T.Object, T.Proxy);
...@@ -1963,66 +1957,6 @@ struct Tests : Rep { ...@@ -1963,66 +1957,6 @@ struct Tests : Rep {
} }
} }
} }
void GlobalObjectType() {
i::Handle<i::Context> context1 = v8::Utils::OpenHandle(
*v8::Context::New(reinterpret_cast<v8::Isolate*>(isolate)));
Handle<i::GlobalObject> global_object1(context1->global_object());
TypeHandle GlobalObjectConstant1 =
Type::Constant(global_object1, Rep::ToRegion(&zone, isolate));
i::Handle<i::Context> context2 = v8::Utils::OpenHandle(
*v8::Context::New(reinterpret_cast<v8::Isolate*>(isolate)));
Handle<i::GlobalObject> global_object2(context2->global_object());
TypeHandle GlobalObjectConstant2 =
Type::Constant(global_object2, Rep::ToRegion(&zone, isolate));
CheckSub(GlobalObjectConstant1, T.DetectableObject);
CheckSub(GlobalObjectConstant2, T.DetectableObject);
CheckSub(GlobalObjectConstant1, T.GlobalObject);
CheckSub(GlobalObjectConstant2, T.GlobalObject);
CheckSub(GlobalObjectConstant1, T.Object);
CheckSub(GlobalObjectConstant2, T.Object);
CheckUnordered(T.GlobalObject, T.OtherObject);
CheckUnordered(GlobalObjectConstant1, T.OtherObject);
CheckUnordered(GlobalObjectConstant2, T.OtherObject);
CheckUnordered(GlobalObjectConstant1, GlobalObjectConstant2);
CheckDisjoint(T.GlobalObject, T.ObjectClass);
CheckDisjoint(GlobalObjectConstant1, T.ObjectClass);
CheckDisjoint(GlobalObjectConstant2, T.ArrayClass);
CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.GlobalObject);
CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), GlobalObjectConstant1);
CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), GlobalObjectConstant2);
CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.GlobalObject);
CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass),
GlobalObjectConstant1);
CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass),
GlobalObjectConstant2);
CheckUnordered(T.Union(T.ObjectClass, T.String), T.GlobalObject);
CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass),
T.Union(T.GlobalObject, T.Object));
CheckDisjoint(T.Union(GlobalObjectConstant1, T.ArrayClass),
GlobalObjectConstant2);
CheckEqual(T.Union(T.Union(T.Number, GlobalObjectConstant1),
T.Union(T.SignedSmall, T.GlobalObject)),
T.Union(T.Number, T.GlobalObject));
CheckEqual(T.Semantic(T.Intersect(T.ObjectClass, T.GlobalObject)), T.None);
CHECK(!T.Intersect(T.ArrayClass, GlobalObjectConstant2)->IsInhabited());
CheckEqual(T.Intersect(T.Union(T.Number, T.OtherObject),
T.Union(T.Signed32, T.GlobalObject)),
T.Signed32);
}
}; };
typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests; typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
...@@ -2197,9 +2131,3 @@ TEST(HTypeFromType_zone) { ZoneTests().HTypeFromType(); } ...@@ -2197,9 +2131,3 @@ TEST(HTypeFromType_zone) { ZoneTests().HTypeFromType(); }
TEST(HTypeFromType_heap) { HeapTests().HTypeFromType(); } TEST(HTypeFromType_heap) { HeapTests().HTypeFromType(); }
TEST(GlobalObjectType_zone) { ZoneTests().GlobalObjectType(); }
TEST(GlobalObjectType_heap) { HeapTests().GlobalObjectType(); }
...@@ -78,13 +78,13 @@ class JSTypeFeedbackTest : public TypedGraphTest { ...@@ -78,13 +78,13 @@ class JSTypeFeedbackTest : public TypedGraphTest {
const char* string, Node* effect, Node* control, const char* string, Node* effect, Node* control,
JSTypeFeedbackSpecializer::DeoptimizationMode mode) { JSTypeFeedbackSpecializer::DeoptimizationMode mode) {
VectorSlotPair feedback; VectorSlotPair feedback;
Node* global = Parameter(Type::GlobalObject()); Node* global = UndefinedConstant();
Node* vector = UndefinedConstant(); Node* vector = UndefinedConstant();
Node* context = UndefinedConstant(); Node* context = UndefinedConstant();
Unique<Name> name = Unique<Name>::CreateUninitialized( Unique<Name> name = Unique<Name>::CreateUninitialized(
isolate()->factory()->InternalizeUtf8String(string)); isolate()->factory()->InternalizeUtf8String(string));
const Operator* op = javascript()->LoadNamed(name, feedback); const Operator* op = javascript()->LoadGlobal(name, feedback);
Node* load = graph()->NewNode(op, global, vector, context); Node* load = graph()->NewNode(op, global, vector, context);
if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) { if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) {
for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op); for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op);
......
...@@ -885,7 +885,7 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) { ...@@ -885,7 +885,7 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) {
}; };
VectorSlotPair feedback; VectorSlotPair feedback;
Node* global = Parameter(Type::GlobalObject()); Node* global = UndefinedConstant();
Node* vector = UndefinedConstant(); Node* vector = UndefinedConstant();
Node* context = UndefinedConstant(); Node* context = UndefinedConstant();
Node* effect = graph()->start(); Node* effect = graph()->start();
...@@ -894,7 +894,7 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) { ...@@ -894,7 +894,7 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) {
for (size_t i = 0; i < arraysize(names); i++) { for (size_t i = 0; i < arraysize(names); i++) {
Unique<Name> name = Unique<Name>::CreateImmovable(names[i]); Unique<Name> name = Unique<Name>::CreateImmovable(names[i]);
Reduction r = Reduce(graph()->NewNode( Reduction r = Reduce(graph()->NewNode(
javascript()->LoadNamed(name, feedback), global, vector, context, javascript()->LoadGlobal(name, feedback), global, vector, context,
EmptyFrameState(), EmptyFrameState(), effect, control)); EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment