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,
// Global var, const, or let variable.
Node* global = BuildLoadGlobalObject();
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);
return value;
}
......@@ -3367,8 +3367,8 @@ Node* AstGraphBuilder::BuildVariableAssignment(
// Global var, const, or let variable.
Node* global = BuildLoadGlobalObject();
Handle<Name> name = variable->name();
Node* store = BuildNamedStore(global, name, value, feedback,
TypeFeedbackId::None());
Node* store = BuildGlobalStore(global, name, value, feedback,
TypeFeedbackId::None());
states.AddToNode(store, bailout_id, combine);
return store;
}
......@@ -3491,10 +3491,8 @@ Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
const VectorSlotPair& feedback,
ContextualMode mode) {
const Operator* op =
javascript()->LoadNamed(MakeUnique(name), feedback, mode);
const VectorSlotPair& feedback) {
const Operator* op = javascript()->LoadNamed(MakeUnique(name), feedback);
Node* node = NewNode(op, object, BuildLoadFeedbackVector());
return Record(js_type_feedback_, node, feedback.slot());
}
......@@ -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) {
return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
......
......@@ -290,11 +290,10 @@ class AstGraphBuilder : public AstVisitor {
Node* BuildKeyedLoad(Node* receiver, Node* key,
const VectorSlotPair& feedback);
Node* BuildNamedLoad(Node* receiver, Handle<Name> name,
const VectorSlotPair& feedback,
ContextualMode mode = NOT_CONTEXTUAL);
const VectorSlotPair& feedback);
Node* BuildKeyedStore(Node* receiver, Node* key, Node* value,
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);
// Builders for super property loads and stores.
......@@ -307,6 +306,12 @@ class AstGraphBuilder : public AstVisitor {
Node* BuildKeyedSuperLoad(Node* receiver, Node* home_object, Node* key,
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.
Node* BuildLoadBuiltinsObject();
Node* BuildLoadGlobalObject();
......
......@@ -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) {
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const StorePropertyParameters& p = StorePropertyParametersOf(node->op());
......@@ -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) {
LanguageMode language_mode = OpParameter<LanguageMode>(node);
ReplaceWithBuiltinCall(node, Builtins::DELETE, 3);
......
......@@ -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,
StoreNamedParameters const& rhs) {
return lhs.language_mode() == rhs.language_mode() &&
......@@ -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,
StorePropertyParameters const& rhs) {
return lhs.language_mode() == rhs.language_mode() &&
......@@ -490,9 +502,8 @@ const Operator* JSOperatorBuilder::CallConstruct(int arguments) {
const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback,
ContextualMode contextual_mode) {
LoadNamedParameters parameters(name, feedback, contextual_mode);
const VectorSlotPair& feedback) {
LoadNamedParameters parameters(name, feedback, NOT_CONTEXTUAL);
return new (zone()) Operator1<LoadNamedParameters>( // --
IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
"JSLoadNamed", // name
......@@ -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,
bool immutable) {
ContextAccess access(depth, index, immutable);
......
......@@ -227,7 +227,7 @@ DynamicContextAccess const& DynamicContextAccessOf(Operator const*);
// 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 {
public:
LoadNamedParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
......@@ -254,6 +254,8 @@ std::ostream& operator<<(std::ostream&, LoadNamedParameters const&);
const LoadNamedParameters& LoadNamedParametersOf(const Operator* op);
const LoadNamedParameters& LoadGlobalParametersOf(const Operator* op);
// Defines the property being loaded from an object. This is
// used as a parameter by JSLoadProperty operators.
......@@ -279,7 +281,7 @@ const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op);
// 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 {
public:
StoreNamedParameters(LanguageMode language_mode,
......@@ -305,6 +307,8 @@ std::ostream& operator<<(std::ostream&, StoreNamedParameters const&);
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
// by JSStoreProperty operators.
......@@ -408,8 +412,7 @@ class JSOperatorBuilder final : public ZoneObject {
const Operator* LoadProperty(const VectorSlotPair& feedback);
const Operator* LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback,
ContextualMode contextual_mode = NOT_CONTEXTUAL);
const VectorSlotPair& feedback);
const Operator* StoreProperty(LanguageMode language_mode,
const VectorSlotPair& feedback);
......@@ -421,6 +424,13 @@ class JSOperatorBuilder final : public ZoneObject {
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* StoreContext(size_t depth, size_t index);
......
......@@ -52,6 +52,8 @@ Reduction JSTypeFeedbackSpecializer::Reduce(Node* node) {
return ReduceJSLoadProperty(node);
case IrOpcode::kJSLoadNamed:
return ReduceJSLoadNamed(node);
case IrOpcode::kJSLoadGlobal:
return ReduceJSLoadGlobal(node);
case IrOpcode::kJSStoreNamed:
return ReduceJSStoreNamed(node);
case IrOpcode::kJSStoreProperty:
......@@ -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) {
DCHECK(node->opcode() == IrOpcode::kJSLoadNamed);
Node* receiver = node->InputAt(0);
if (IsGlobalObject(receiver)) {
return ReduceJSLoadNamedForGlobalVariable(node);
}
if (mode() != kDeoptimizationEnabled) return NoChange();
Node* frame_state_before = GetFrameStateBefore(node);
if (frame_state_before == nullptr) return NoChange();
......@@ -166,6 +157,7 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) {
}
oracle()->PropertyReceiverTypes(slot, name, &maps);
Node* receiver = node->InputAt(0);
Node* effect = NodeProperties::GetEffectInput(node);
if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism
......@@ -196,10 +188,10 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) {
}
Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamedForGlobalVariable(
Node* node) {
Reduction JSTypeFeedbackSpecializer::ReduceJSLoadGlobal(Node* node) {
DCHECK(node->opcode() == IrOpcode::kJSLoadGlobal);
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.
Handle<Object> constant_value =
jsgraph()->isolate()->factory()->GlobalConstantFor(name);
......
......@@ -84,8 +84,8 @@ class JSTypeFeedbackSpecializer : public AdvancedReducer {
Reduction Reduce(Node* node) override;
// Visible for unit testing.
Reduction ReduceJSLoadGlobal(Node* node);
Reduction ReduceJSLoadNamed(Node* node);
Reduction ReduceJSLoadNamedForGlobalVariable(Node* node);
Reduction ReduceJSLoadProperty(Node* node);
Reduction ReduceJSStoreNamed(Node* node);
Reduction ReduceJSStoreProperty(Node* node);
......
......@@ -801,18 +801,14 @@ Reduction JSTypedLowering::ReduceJSToString(Node* node) {
}
Reduction JSTypedLowering::ReduceJSLoadNamed(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".
Handle<Name> name = LoadNamedParametersOf(node->op()).name().handle();
Handle<Object> constant_value = factory()->GlobalConstantFor(name);
if (!constant_value.is_null()) {
Node* constant = jsgraph()->Constant(constant_value);
ReplaceWithValue(node, constant);
return Replace(constant);
}
Reduction JSTypedLowering::ReduceJSLoadGlobal(Node* node) {
// Optimize global constants like "undefined", "Infinity", and "NaN".
Handle<Name> name = LoadGlobalParametersOf(node->op()).name().handle();
Handle<Object> constant_value = factory()->GlobalConstantFor(name);
if (!constant_value.is_null()) {
Node* constant = jsgraph()->Constant(constant_value);
ReplaceWithValue(node, constant);
return Replace(constant);
}
return NoChange();
}
......@@ -1023,7 +1019,7 @@ Reduction JSTypedLowering::ReduceJSLoadDynamicGlobal(Node* node) {
javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true), context,
context, effect);
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);
// Slow case, because variable potentially shadowed. Perform dynamic lookup.
......@@ -1639,8 +1635,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceJSToNumber(node);
case IrOpcode::kJSToString:
return ReduceJSToString(node);
case IrOpcode::kJSLoadNamed:
return ReduceJSLoadNamed(node);
case IrOpcode::kJSLoadGlobal:
return ReduceJSLoadGlobal(node);
case IrOpcode::kJSLoadProperty:
return ReduceJSLoadProperty(node);
case IrOpcode::kJSStoreProperty:
......
......@@ -41,7 +41,7 @@ class JSTypedLowering final : public AdvancedReducer {
Reduction ReduceJSBitwiseOr(Node* node);
Reduction ReduceJSMultiply(Node* node);
Reduction ReduceJSComparison(Node* node);
Reduction ReduceJSLoadNamed(Node* node);
Reduction ReduceJSLoadGlobal(Node* node);
Reduction ReduceJSLoadProperty(Node* node);
Reduction ReduceJSStoreProperty(Node* node);
Reduction ReduceJSLoadContext(Node* node);
......
......@@ -114,8 +114,10 @@
V(JSCreateLiteralObject) \
V(JSLoadProperty) \
V(JSLoadNamed) \
V(JSLoadGlobal) \
V(JSStoreProperty) \
V(JSStoreNamed) \
V(JSStoreGlobal) \
V(JSDeleteProperty) \
V(JSHasProperty) \
V(JSInstanceOf)
......
......@@ -71,6 +71,8 @@ int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
case IrOpcode::kJSStoreNamed:
case IrOpcode::kJSLoadProperty:
case IrOpcode::kJSStoreProperty:
case IrOpcode::kJSLoadGlobal:
case IrOpcode::kJSStoreGlobal:
case IrOpcode::kJSLoadDynamicGlobal:
return 2;
......
......@@ -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
// a (smaller) range to this node. This is used to speed up
// the fixpoint calculation in case there appears to be a loop
......@@ -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) {
return Bounds(Type::None(zone()), Type::Boolean(zone()));
}
......@@ -1453,12 +1464,9 @@ Bounds Typer::Visitor::TypeJSLoadContext(Node* node) {
ContextAccess access = OpParameter<ContextAccess>(node);
Bounds outer = Operand(node, 0);
Type* context_type = outer.upper;
Type* upper = (access.index() == Context::GLOBAL_OBJECT_INDEX)
? Type::GlobalObject()
: Type::Any();
if (context_type->Is(Type::None())) {
// 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()));
......@@ -1488,7 +1496,7 @@ Bounds Typer::Visitor::TypeJSLoadContext(Node* node) {
handle(context.ToHandleChecked()->get(static_cast<int>(access.index())),
isolate()));
}
return Bounds(lower, upper);
return Bounds(lower, Type::Any());
}
......
......@@ -521,11 +521,13 @@ void Verifier::Visitor::Check(Node* node) {
break;
case IrOpcode::kJSLoadProperty:
case IrOpcode::kJSLoadNamed:
case IrOpcode::kJSLoadGlobal:
// Type can be anything.
CheckUpperIs(node, Type::Any());
break;
case IrOpcode::kJSStoreProperty:
case IrOpcode::kJSStoreNamed:
case IrOpcode::kJSStoreGlobal:
// Type is empty.
CheckNotTyped(node);
break;
......
......@@ -235,6 +235,7 @@ TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
case JS_GENERATOR_OBJECT_TYPE:
case JS_MODULE_TYPE:
case JS_BUILTINS_OBJECT_TYPE:
case JS_GLOBAL_OBJECT_TYPE:
case JS_GLOBAL_PROXY_TYPE:
case JS_ARRAY_BUFFER_TYPE:
case JS_ARRAY_TYPE:
......@@ -248,8 +249,6 @@ TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
case JS_WEAK_SET_TYPE:
if (map->is_undetectable()) return kUndetectable;
return kOtherObject;
case JS_GLOBAL_OBJECT_TYPE:
return kGlobalObject;
case JS_FUNCTION_TYPE:
return kOtherObject; // TODO(rossberg): there should be a Function type.
case JS_REGEXP_TYPE:
......
......@@ -208,7 +208,7 @@ namespace internal {
V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \
V(OtherString, 1u << 14 | 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(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \
V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \
......@@ -232,10 +232,9 @@ namespace internal {
V(NumberOrUndefined, kNumber | kUndefined) \
V(PlainPrimitive, kNumberOrString | kBoolean | kNullOrUndefined) \
V(Primitive, kSymbol | kPlainPrimitive) \
V(DetectableObject, kGlobalObject | kOtherObject) \
V(DetectableReceiver, kDetectableObject | kProxy) \
V(DetectableReceiver, kOtherObject | kProxy) \
V(Detectable, kDetectableReceiver | kNumber | kName) \
V(Object, kDetectableObject | kUndetectable) \
V(Object, kOtherObject | kUndetectable) \
V(Receiver, kObject | kProxy) \
V(ReceiverOrUndefined, kReceiver | kUndefined) \
V(StringOrReceiver, kString | kReceiver) \
......
......@@ -1020,15 +1020,10 @@ struct Tests : Rep {
CheckSub(T.Proxy, T.Receiver);
CheckSub(T.OtherObject, T.Object);
CheckSub(T.Undetectable, T.Object);
CheckSub(T.DetectableObject, T.Object);
CheckSub(T.GlobalObject, T.DetectableObject);
CheckSub(T.OtherObject, T.DetectableObject);
CheckSub(T.GlobalObject, T.Object);
CheckSub(T.GlobalObject, T.Receiver);
CheckSub(T.OtherObject, T.Object);
CheckUnordered(T.Object, T.Proxy);
CheckUnordered(T.GlobalObject, T.OtherObject);
CheckUnordered(T.DetectableObject, T.Undetectable);
CheckUnordered(T.OtherObject, T.Undetectable);
// Subtyping between concrete structural types
......@@ -1350,7 +1345,6 @@ struct Tests : Rep {
CheckDisjoint(T.InternalizedString, T.Symbol);
CheckOverlap(T.Object, T.Receiver);
CheckOverlap(T.OtherObject, T.Object);
CheckOverlap(T.GlobalObject, T.Object);
CheckOverlap(T.Proxy, T.Receiver);
CheckDisjoint(T.Object, T.Proxy);
......@@ -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;
......@@ -2197,9 +2131,3 @@ TEST(HTypeFromType_zone) { ZoneTests().HTypeFromType(); }
TEST(HTypeFromType_heap) { HeapTests().HTypeFromType(); }
TEST(GlobalObjectType_zone) { ZoneTests().GlobalObjectType(); }
TEST(GlobalObjectType_heap) { HeapTests().GlobalObjectType(); }
......@@ -78,13 +78,13 @@ class JSTypeFeedbackTest : public TypedGraphTest {
const char* string, Node* effect, Node* control,
JSTypeFeedbackSpecializer::DeoptimizationMode mode) {
VectorSlotPair feedback;
Node* global = Parameter(Type::GlobalObject());
Node* global = UndefinedConstant();
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Unique<Name> name = Unique<Name>::CreateUninitialized(
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);
if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) {
for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op);
......
......@@ -885,7 +885,7 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) {
};
VectorSlotPair feedback;
Node* global = Parameter(Type::GlobalObject());
Node* global = UndefinedConstant();
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
Node* effect = graph()->start();
......@@ -894,7 +894,7 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) {
for (size_t i = 0; i < arraysize(names); i++) {
Unique<Name> name = Unique<Name>::CreateImmovable(names[i]);
Reduction r = Reduce(graph()->NewNode(
javascript()->LoadNamed(name, feedback), global, vector, context,
javascript()->LoadGlobal(name, feedback), global, vector, context,
EmptyFrameState(), EmptyFrameState(), effect, control));
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