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