Commit 160d0a18 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Parser] Remove Variable::is_possibly_eval.

Removes Variable::is_possibly_eval() and instead stores whether
a call is possibly eval in the Call node's bitfield.

Also removes HandleDereferenceMode since it's no longer used.

BUG=v8:5203

Review-Url: https://codereview.chromium.org/2242583003
Cr-Commit-Position: refs/heads/master@{#38633}
parent 75a20458
...@@ -1262,7 +1262,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> { ...@@ -1262,7 +1262,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
} }
void VisitCall(Call* expr) { void VisitCall(Call* expr) {
Call::CallType call_type = expr->GetCallType(isolate_); Call::CallType call_type = expr->GetCallType();
switch (call_type) { switch (call_type) {
case Call::OTHER_CALL: { case Call::OTHER_CALL: {
DCHECK_EQ(kFuncScope, scope_); DCHECK_EQ(kFuncScope, scope_);
......
...@@ -887,38 +887,31 @@ bool Expression::IsMonomorphic() const { ...@@ -887,38 +887,31 @@ bool Expression::IsMonomorphic() const {
} }
} }
bool Call::IsUsingCallFeedbackICSlot( bool Call::IsUsingCallFeedbackICSlot() const {
Isolate* isolate, HandleDereferenceMode dereference_mode) const { return GetCallType() != POSSIBLY_EVAL_CALL;
CallType call_type = GetCallType(isolate, dereference_mode);
if (call_type == POSSIBLY_EVAL_CALL) {
return false;
}
return true;
} }
bool Call::IsUsingCallFeedbackSlot( bool Call::IsUsingCallFeedbackSlot() const {
Isolate* isolate, HandleDereferenceMode dereference_mode) const {
// SuperConstructorCall uses a CallConstructStub, which wants // SuperConstructorCall uses a CallConstructStub, which wants
// a Slot, in addition to any IC slots requested elsewhere. // a Slot, in addition to any IC slots requested elsewhere.
return GetCallType(isolate, dereference_mode) == SUPER_CALL; return GetCallType() == SUPER_CALL;
} }
void Call::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, void Call::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) { FeedbackVectorSlotCache* cache) {
if (IsUsingCallFeedbackICSlot(isolate)) { if (IsUsingCallFeedbackICSlot()) {
ic_slot_ = spec->AddCallICSlot(); ic_slot_ = spec->AddCallICSlot();
} }
if (IsUsingCallFeedbackSlot(isolate)) { if (IsUsingCallFeedbackSlot()) {
stub_slot_ = spec->AddGeneralSlot(); stub_slot_ = spec->AddGeneralSlot();
} }
} }
Call::CallType Call::GetCallType(Isolate* isolate, Call::CallType Call::GetCallType() const {
HandleDereferenceMode deref_mode) const {
VariableProxy* proxy = expression()->AsVariableProxy(); VariableProxy* proxy = expression()->AsVariableProxy();
if (proxy != NULL) { if (proxy != NULL) {
if (proxy->var()->is_possibly_eval(isolate, deref_mode)) { if (is_possibly_eval()) {
return POSSIBLY_EVAL_CALL; return POSSIBLY_EVAL_CALL;
} else if (proxy->var()->IsUnallocatedOrGlobalSlot()) { } else if (proxy->var()->IsUnallocatedOrGlobalSlot()) {
return GLOBAL_CALL; return GLOBAL_CALL;
......
...@@ -1738,9 +1738,7 @@ class Property final : public Expression { ...@@ -1738,9 +1738,7 @@ class Property final : public Expression {
} }
// Returns the properties assign type. // Returns the properties assign type.
static LhsKind GetAssignType( static LhsKind GetAssignType(Property* property) {
Property* property,
HandleDereferenceMode deref_mode = HandleDereferenceMode::kAllowed) {
if (property == NULL) return VARIABLE; if (property == NULL) return VARIABLE;
bool super_access = property->IsSuperAccess(); bool super_access = property->IsSuperAccess();
return (property->key()->IsPropertyName()) return (property->key()->IsPropertyName())
...@@ -1839,6 +1837,10 @@ class Call final : public Expression { ...@@ -1839,6 +1837,10 @@ class Call final : public Expression {
bit_field_ = IsUninitializedField::update(bit_field_, b); bit_field_ = IsUninitializedField::update(bit_field_, b);
} }
bool is_possibly_eval() const {
return IsPossiblyEvalField::decode(bit_field_);
}
TailCallMode tail_call_mode() const { TailCallMode tail_call_mode() const {
return IsTailField::decode(bit_field_) ? TailCallMode::kAllow return IsTailField::decode(bit_field_) ? TailCallMode::kAllow
: TailCallMode::kDisallow; : TailCallMode::kDisallow;
...@@ -1857,18 +1859,15 @@ class Call final : public Expression { ...@@ -1857,18 +1859,15 @@ class Call final : public Expression {
OTHER_CALL OTHER_CALL
}; };
enum PossiblyEval {
IS_POSSIBLY_EVAL,
NOT_EVAL,
};
// Helpers to determine how to handle the call. // Helpers to determine how to handle the call.
// If called with |deref_mode| of kDisallowed, then the AST nodes must have CallType GetCallType() const;
// been internalized within a CanonicalHandleScope. bool IsUsingCallFeedbackSlot() const;
CallType GetCallType( bool IsUsingCallFeedbackICSlot() const;
Isolate* isolate,
HandleDereferenceMode deref_mode = HandleDereferenceMode::kAllowed) const;
bool IsUsingCallFeedbackSlot(
Isolate* isolate,
HandleDereferenceMode deref_mode = HandleDereferenceMode::kAllowed) const;
bool IsUsingCallFeedbackICSlot(
Isolate* isolate,
HandleDereferenceMode deref_mode = HandleDereferenceMode::kAllowed) const;
#ifdef DEBUG #ifdef DEBUG
// Used to assert that the FullCodeGenerator records the return site. // Used to assert that the FullCodeGenerator records the return site.
...@@ -1879,9 +1878,11 @@ class Call final : public Expression { ...@@ -1879,9 +1878,11 @@ class Call final : public Expression {
friend class AstNodeFactory; friend class AstNodeFactory;
Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments, Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
int pos) int pos, PossiblyEval possibly_eval)
: Expression(zone, pos, kCall), : Expression(zone, pos, kCall),
bit_field_(IsUninitializedField::encode(false)), bit_field_(
IsUninitializedField::encode(false) |
IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL)),
expression_(expression), expression_(expression),
arguments_(arguments) { arguments_(arguments) {
if (expression->IsProperty()) { if (expression->IsProperty()) {
...@@ -1894,6 +1895,7 @@ class Call final : public Expression { ...@@ -1894,6 +1895,7 @@ class Call final : public Expression {
class IsUninitializedField : public BitField8<bool, 0, 1> {}; class IsUninitializedField : public BitField8<bool, 0, 1> {};
class IsTailField : public BitField8<bool, 1, 1> {}; class IsTailField : public BitField8<bool, 1, 1> {};
class IsPossiblyEvalField : public BitField8<bool, 2, 1> {};
uint8_t bit_field_; uint8_t bit_field_;
FeedbackVectorSlot ic_slot_; FeedbackVectorSlot ic_slot_;
...@@ -3241,10 +3243,9 @@ class AstNodeFactory final BASE_EMBEDDED { ...@@ -3241,10 +3243,9 @@ class AstNodeFactory final BASE_EMBEDDED {
return new (zone_) Property(zone_, obj, key, pos); return new (zone_) Property(zone_, obj, key, pos);
} }
Call* NewCall(Expression* expression, Call* NewCall(Expression* expression, ZoneList<Expression*>* arguments,
ZoneList<Expression*>* arguments, int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) {
int pos) { return new (zone_) Call(zone_, expression, arguments, pos, possibly_eval);
return new (zone_) Call(zone_, expression, arguments, pos);
} }
CallNew* NewCallNew(Expression* expression, CallNew* NewCallNew(Expression* expression,
......
...@@ -82,17 +82,6 @@ class Variable: public ZoneObject { ...@@ -82,17 +82,6 @@ class Variable: public ZoneObject {
bool is_this() const { return kind_ == THIS; } bool is_this() const { return kind_ == THIS; }
bool is_arguments() const { return kind_ == ARGUMENTS; } bool is_arguments() const { return kind_ == ARGUMENTS; }
// True if the variable is named eval and not known to be shadowed.
bool is_possibly_eval(Isolate* isolate,
HandleDereferenceMode deref_mode =
HandleDereferenceMode::kAllowed) const {
// Note: it is safe to dereference isolate->factory()->eval_string() here
// regardless of |deref_mode| because it is a constant root and so will
// never be updated or moved.
return !is_this() &&
name_is_identical_to(isolate->factory()->eval_string(), deref_mode);
}
Variable* local_if_not_shadowed() const { Variable* local_if_not_shadowed() const {
DCHECK(mode_ == DYNAMIC_LOCAL && local_if_not_shadowed_ != NULL); DCHECK(mode_ == DYNAMIC_LOCAL && local_if_not_shadowed_ != NULL);
return local_if_not_shadowed_; return local_if_not_shadowed_;
...@@ -116,20 +105,6 @@ class Variable: public ZoneObject { ...@@ -116,20 +105,6 @@ class Variable: public ZoneObject {
static int CompareIndex(Variable* const* v, Variable* const* w); static int CompareIndex(Variable* const* v, Variable* const* w);
private: private:
bool name_is_identical_to(Handle<Object> object,
HandleDereferenceMode deref_mode) const {
if (deref_mode == HandleDereferenceMode::kAllowed) {
return *name() == *object;
} else {
// If handle dereference isn't allowed use the handle address for
// identity. This depends on the variable name being internalized in a
// CanonicalHandleScope, so that all handles created during the
// internalization with identical values have identical locations, and any
// handles created which point to roots have the root handle's location.
return name().address() == object.address();
}
}
Scope* scope_; Scope* scope_;
const AstRawString* name_; const AstRawString* name_;
VariableMode mode_; VariableMode mode_;
......
...@@ -2277,7 +2277,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) { ...@@ -2277,7 +2277,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
void AstGraphBuilder::VisitCall(Call* expr) { void AstGraphBuilder::VisitCall(Call* expr) {
Expression* callee = expr->expression(); Expression* callee = expr->expression();
Call::CallType call_type = expr->GetCallType(isolate()); Call::CallType call_type = expr->GetCallType();
// Prepare the callee and the receiver to the function call. This depends on // Prepare the callee and the receiver to the function call. This depends on
// the semantics of the underlying call type. // the semantics of the underlying call type.
......
...@@ -9828,8 +9828,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { ...@@ -9828,8 +9828,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
PushArgumentsFromEnvironment(argument_count); PushArgumentsFromEnvironment(argument_count);
} else { } else {
VariableProxy* proxy = expr->expression()->AsVariableProxy(); if (expr->is_possibly_eval()) {
if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
return Bailout(kPossibleDirectCallToEval); return Bailout(kPossibleDirectCallToEval);
} }
...@@ -9874,8 +9873,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { ...@@ -9874,8 +9873,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
syntactic_tail_call_mode, tail_call_mode); syntactic_tail_call_mode, tail_call_mode);
} else { } else {
PushArgumentsFromEnvironment(argument_count); PushArgumentsFromEnvironment(argument_count);
if (expr->is_uninitialized() && if (expr->is_uninitialized() && expr->IsUsingCallFeedbackICSlot()) {
expr->IsUsingCallFeedbackICSlot(isolate())) {
// We've never seen this call before, so let's have Crankshaft learn // We've never seen this call before, so let's have Crankshaft learn
// through the type vector. // through the type vector.
call = NewCallFunctionViaIC(function, argument_count, call = NewCallFunctionViaIC(function, argument_count,
......
...@@ -515,7 +515,7 @@ void AstTyper::VisitCall(Call* expr) { ...@@ -515,7 +515,7 @@ void AstTyper::VisitCall(Call* expr) {
// Collect type feedback. // Collect type feedback.
RECURSE(Visit(expr->expression())); RECURSE(Visit(expr->expression()));
bool is_uninitialized = true; bool is_uninitialized = true;
if (expr->IsUsingCallFeedbackICSlot(isolate_)) { if (expr->IsUsingCallFeedbackICSlot()) {
FeedbackVectorSlot slot = expr->CallFeedbackICSlot(); FeedbackVectorSlot slot = expr->CallFeedbackICSlot();
is_uninitialized = oracle()->CallIsUninitialized(slot); is_uninitialized = oracle()->CallIsUninitialized(slot);
if (!expr->expression()->IsProperty() && if (!expr->expression()->IsProperty() &&
...@@ -534,8 +534,7 @@ void AstTyper::VisitCall(Call* expr) { ...@@ -534,8 +534,7 @@ void AstTyper::VisitCall(Call* expr) {
RECURSE(Visit(arg)); RECURSE(Visit(arg));
} }
VariableProxy* proxy = expr->expression()->AsVariableProxy(); if (expr->is_possibly_eval()) {
if (proxy != NULL && proxy->var()->is_possibly_eval(isolate_)) {
store_.Forget(); // Eval could do whatever to local variables. store_.Forget(); // Eval could do whatever to local variables.
} }
......
...@@ -1564,7 +1564,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { ...@@ -1564,7 +1564,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
? "[ TailCall" ? "[ TailCall"
: "[ Call"); : "[ Call");
Expression* callee = expr->expression(); Expression* callee = expr->expression();
Call::CallType call_type = expr->GetCallType(isolate()); Call::CallType call_type = expr->GetCallType();
switch (call_type) { switch (call_type) {
case Call::POSSIBLY_EVAL_CALL: case Call::POSSIBLY_EVAL_CALL:
......
...@@ -816,8 +816,6 @@ enum class CreateArgumentsType : uint8_t { ...@@ -816,8 +816,6 @@ enum class CreateArgumentsType : uint8_t {
kRestParameter kRestParameter
}; };
enum class HandleDereferenceMode { kAllowed, kDisallowed };
inline size_t hash_value(CreateArgumentsType type) { inline size_t hash_value(CreateArgumentsType type) {
return bit_cast<uint8_t>(type); return bit_cast<uint8_t>(type);
} }
......
...@@ -1170,8 +1170,7 @@ void BytecodeGenerator::VisitForInAssignment(Expression* expr, ...@@ -1170,8 +1170,7 @@ void BytecodeGenerator::VisitForInAssignment(Expression* expr,
// Evaluate assignment starting with the value to be stored in the // Evaluate assignment starting with the value to be stored in the
// accumulator. // accumulator.
Property* property = expr->AsProperty(); Property* property = expr->AsProperty();
LhsKind assign_type = LhsKind assign_type = Property::GetAssignType(property);
Property::GetAssignType(property, HandleDereferenceMode::kDisallowed);
switch (assign_type) { switch (assign_type) {
case VARIABLE: { case VARIABLE: {
Variable* variable = expr->AsVariableProxy()->var(); Variable* variable = expr->AsVariableProxy()->var();
...@@ -2141,8 +2140,7 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -2141,8 +2140,7 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
// Left-hand side can only be a property, a global or a variable slot. // Left-hand side can only be a property, a global or a variable slot.
Property* property = expr->target()->AsProperty(); Property* property = expr->target()->AsProperty();
LhsKind assign_type = LhsKind assign_type = Property::GetAssignType(property);
Property::GetAssignType(property, HandleDereferenceMode::kDisallowed);
// Evaluate LHS expression. // Evaluate LHS expression.
switch (assign_type) { switch (assign_type) {
...@@ -2372,8 +2370,7 @@ void BytecodeGenerator::VisitThrow(Throw* expr) { ...@@ -2372,8 +2370,7 @@ void BytecodeGenerator::VisitThrow(Throw* expr) {
} }
void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
LhsKind property_kind = LhsKind property_kind = Property::GetAssignType(expr);
Property::GetAssignType(expr, HandleDereferenceMode::kDisallowed);
FeedbackVectorSlot slot = expr->PropertyFeedbackSlot(); FeedbackVectorSlot slot = expr->PropertyFeedbackSlot();
builder()->SetExpressionPosition(expr); builder()->SetExpressionPosition(expr);
switch (property_kind) { switch (property_kind) {
...@@ -2451,8 +2448,7 @@ void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, ...@@ -2451,8 +2448,7 @@ void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property,
} }
void BytecodeGenerator::VisitProperty(Property* expr) { void BytecodeGenerator::VisitProperty(Property* expr) {
LhsKind property_kind = LhsKind property_kind = Property::GetAssignType(expr);
Property::GetAssignType(expr, HandleDereferenceMode::kDisallowed);
if (property_kind != NAMED_SUPER_PROPERTY && if (property_kind != NAMED_SUPER_PROPERTY &&
property_kind != KEYED_SUPER_PROPERTY) { property_kind != KEYED_SUPER_PROPERTY) {
Register obj = VisitForRegisterValue(expr->obj()); Register obj = VisitForRegisterValue(expr->obj());
...@@ -2496,8 +2492,7 @@ Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { ...@@ -2496,8 +2492,7 @@ Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) {
void BytecodeGenerator::VisitCall(Call* expr) { void BytecodeGenerator::VisitCall(Call* expr) {
Expression* callee_expr = expr->expression(); Expression* callee_expr = expr->expression();
Call::CallType call_type = Call::CallType call_type = expr->GetCallType();
expr->GetCallType(isolate(), HandleDereferenceMode::kDisallowed);
if (call_type == Call::SUPER_CALL) { if (call_type == Call::SUPER_CALL) {
return VisitCallSuper(expr); return VisitCallSuper(expr);
...@@ -2815,8 +2810,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -2815,8 +2810,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
// Left-hand side can only be a property, a global or a variable slot. // Left-hand side can only be a property, a global or a variable slot.
Property* property = expr->expression()->AsProperty(); Property* property = expr->expression()->AsProperty();
LhsKind assign_type = LhsKind assign_type = Property::GetAssignType(property);
Property::GetAssignType(property, HandleDereferenceMode::kDisallowed);
bool is_postfix = expr->is_postfix() && !execution_result()->IsEffect(); bool is_postfix = expr->is_postfix() && !execution_result()->IsEffect();
......
...@@ -1160,7 +1160,8 @@ class ParserBase : public Traits { ...@@ -1160,7 +1160,8 @@ class ParserBase : public Traits {
// Keep track of eval() calls since they disable all local variable // Keep track of eval() calls since they disable all local variable
// optimizations. This checks if expression is an eval call, and if yes, // optimizations. This checks if expression is an eval call, and if yes,
// forwards the information to scope. // forwards the information to scope.
void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) { Call::PossiblyEval CheckPossibleEvalCall(ExpressionT expression,
Scope* scope) {
if (Traits::IsIdentifier(expression) && if (Traits::IsIdentifier(expression) &&
Traits::IsEval(Traits::AsIdentifier(expression))) { Traits::IsEval(Traits::AsIdentifier(expression))) {
scope->RecordEvalCall(); scope->RecordEvalCall();
...@@ -1169,7 +1170,9 @@ class ParserBase : public Traits { ...@@ -1169,7 +1170,9 @@ class ParserBase : public Traits {
// in case it includes declarations that will be hoisted. // in case it includes declarations that will be hoisted.
scope->GetDeclarationScope()->RecordEvalCall(); scope->GetDeclarationScope()->RecordEvalCall();
} }
return Call::IS_POSSIBLY_EVAL;
} }
return Call::NOT_EVAL;
} }
// Used to validate property names in object literals and class literals // Used to validate property names in object literals and class literals
...@@ -2924,14 +2927,15 @@ ParserBase<Traits>::ParseLeftHandSideExpression( ...@@ -2924,14 +2927,15 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
// no explicit receiver. // no explicit receiver.
// These calls are marked as potentially direct eval calls. Whether // These calls are marked as potentially direct eval calls. Whether
// they are actually direct calls to eval is determined at run time. // they are actually direct calls to eval is determined at run time.
this->CheckPossibleEvalCall(result, scope()); Call::PossiblyEval is_possibly_eval =
CheckPossibleEvalCall(result, scope());
bool is_super_call = result->IsSuperCallReference(); bool is_super_call = result->IsSuperCallReference();
if (spread_pos.IsValid()) { if (spread_pos.IsValid()) {
args = Traits::PrepareSpreadArguments(args); args = Traits::PrepareSpreadArguments(args);
result = Traits::SpreadCall(result, args, pos); result = Traits::SpreadCall(result, args, pos);
} else { } else {
result = factory()->NewCall(result, args, pos); result = factory()->NewCall(result, args, pos, is_possibly_eval);
} }
// Explicit calls to the super constructor using super() perform an // Explicit calls to the super constructor using super() perform an
......
...@@ -520,10 +520,11 @@ class PreParserFactory { ...@@ -520,10 +520,11 @@ class PreParserFactory {
int pos) { int pos) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
PreParserExpression NewCall(PreParserExpression expression, PreParserExpression NewCall(
PreParserExpressionList arguments, PreParserExpression expression, PreParserExpressionList arguments,
int pos) { int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) {
if (expression.IsIdentifier() && expression.AsIdentifier().IsEval()) { if (possibly_eval == Call::IS_POSSIBLY_EVAL) {
DCHECK(expression.IsIdentifier() && expression.AsIdentifier().IsEval());
return PreParserExpression::CallEval(); return PreParserExpression::CallEval();
} }
return PreParserExpression::Call(); return PreParserExpression::Call();
......
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