Moving logic to AstNode to determine how many type cells are required.

With this change, we'll be able to discover how many type cells we
need at parse time, enabling future optimizations.

R=bmeurer@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18668 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b2bea462
......@@ -2721,10 +2721,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
Comment cmnt(masm_, "[ Call");
Expression* callee = expr->expression();
VariableProxy* proxy = callee->AsVariableProxy();
Property* property = callee->AsProperty();
Call::CallType call_type = expr->GetCallType(isolate());
if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
if (call_type == Call::POSSIBLY_EVAL_CALL) {
// In a call to eval, we first call %ResolvePossiblyDirectEval to
// resolve the function we need to call and the receiver of the
// call. Then we call the resolved function using the given
......@@ -2763,13 +2762,15 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, r0);
} else if (proxy != NULL && proxy->var()->IsUnallocated()) {
} else if (call_type == Call::GLOBAL_CALL) {
// Push global object as receiver for the call IC.
__ ldr(r0, GlobalObjectOperand());
__ push(r0);
VariableProxy* proxy = callee->AsVariableProxy();
EmitCallWithIC(expr, proxy->name(), CONTEXTUAL);
} else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
// Call to a lookup slot (dynamically introduced variable).
VariableProxy* proxy = callee->AsVariableProxy();
Label slow, done;
{ PreservePositionScope scope(masm()->positions_recorder());
......@@ -2806,7 +2807,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// The receiver is either the global receiver or an object found
// by LoadContextSlot.
EmitCallWithStub(expr);
} else if (property != NULL) {
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
......@@ -2818,6 +2820,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitKeyedCallWithIC(expr, property->key());
}
} else {
ASSERT(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
......
......@@ -590,12 +590,28 @@ bool FunctionDeclaration::IsInlineable() const {
// TODO(rossberg): all RecordTypeFeedback functions should disappear
// once we use the common type field in the AST consistently.
void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
to_boolean_types_ = oracle->ToBooleanTypes(test_id());
}
Call::CallType Call::GetCallType(Isolate* isolate) const {
VariableProxy* proxy = expression()->AsVariableProxy();
if (proxy != NULL) {
if (proxy->var()->is_possibly_eval(isolate)) {
return POSSIBLY_EVAL_CALL;
} else if (proxy->var()->IsUnallocated()) {
return GLOBAL_CALL;
} else if (proxy->var()->IsLookupSlot()) {
return LOOKUP_SLOT_CALL;
}
}
Property* property = expression()->AsProperty();
return property != NULL ? PROPERTY_CALL : OTHER_CALL;
}
bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
// If there is an interceptor, we can't compute the target for a direct call.
if (type->has_named_interceptor()) return false;
......
......@@ -1774,6 +1774,17 @@ class Call V8_FINAL : public Expression {
BailoutId ReturnId() const { return return_id_; }
enum CallType {
POSSIBLY_EVAL_CALL,
GLOBAL_CALL,
LOOKUP_SLOT_CALL,
PROPERTY_CALL,
OTHER_CALL
};
// Helpers to determine how to handle the call.
CallType GetCallType(Isolate* isolate) const;
// TODO(rossberg): this should really move somewhere else (and be merged with
// various similar methods in objets.cc), but for now...
static Handle<JSObject> GetPrototypeForPrimitiveCheck(
......
......@@ -2673,10 +2673,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
Comment cmnt(masm_, "[ Call");
Expression* callee = expr->expression();
VariableProxy* proxy = callee->AsVariableProxy();
Property* property = callee->AsProperty();
Call::CallType call_type = expr->GetCallType(isolate());
if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
if (call_type == Call::POSSIBLY_EVAL_CALL) {
// In a call to eval, we first call %ResolvePossiblyDirectEval to
// resolve the function we need to call and the receiver of the call.
// Then we call the resolved function using the given arguments.
......@@ -2711,12 +2710,14 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, eax);
} else if (proxy != NULL && proxy->var()->IsUnallocated()) {
} else if (call_type == Call::GLOBAL_CALL) {
// Push global object as receiver for the call IC.
__ push(GlobalObjectOperand());
VariableProxy* proxy = callee->AsVariableProxy();
EmitCallWithIC(expr, proxy->name(), CONTEXTUAL);
} else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
// Call to a lookup slot (dynamically introduced variable).
VariableProxy* proxy = callee->AsVariableProxy();
Label slow, done;
{ PreservePositionScope scope(masm()->positions_recorder());
// Generate code for loading from variables potentially shadowed by
......@@ -2750,7 +2751,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// LoadContextSlot.
EmitCallWithStub(expr);
} else if (property != NULL) {
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
......@@ -2763,6 +2765,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
}
} else {
ASSERT(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
......
......@@ -2755,10 +2755,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
Comment cmnt(masm_, "[ Call");
Expression* callee = expr->expression();
VariableProxy* proxy = callee->AsVariableProxy();
Property* property = callee->AsProperty();
Call::CallType call_type = expr->GetCallType(isolate());
if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
if (call_type == Call::POSSIBLY_EVAL_CALL) {
// In a call to eval, we first call %ResolvePossiblyDirectEval to
// resolve the function we need to call and the receiver of the
// call. Then we call the resolved function using the given
......@@ -2796,13 +2795,15 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// Restore context register.
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, v0);
} else if (proxy != NULL && proxy->var()->IsUnallocated()) {
} else if (call_type == Call::GLOBAL_CALL) {
// Push global object as receiver for the call IC.
__ lw(a0, GlobalObjectOperand());
__ push(a0);
VariableProxy* proxy = callee->AsVariableProxy();
EmitCallWithIC(expr, proxy->name(), CONTEXTUAL);
} else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
// Call to a lookup slot (dynamically introduced variable).
VariableProxy* proxy = callee->AsVariableProxy();
Label slow, done;
{ PreservePositionScope scope(masm()->positions_recorder());
......@@ -2839,7 +2840,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// The receiver is either the global receiver or an object found
// by LoadContextSlot.
EmitCallWithStub(expr);
} else if (property != NULL) {
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
......@@ -2851,6 +2853,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitKeyedCallWithIC(expr, property->key());
}
} else {
ASSERT(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
......
......@@ -2658,10 +2658,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
Comment cmnt(masm_, "[ Call");
Expression* callee = expr->expression();
VariableProxy* proxy = callee->AsVariableProxy();
Property* property = callee->AsProperty();
Call::CallType call_type = expr->GetCallType(isolate());
if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
if (call_type == Call::POSSIBLY_EVAL_CALL) {
// In a call to eval, we first call %ResolvePossiblyDirectEval to
// resolve the function we need to call and the receiver of the call.
// Then we call the resolved function using the given arguments.
......@@ -2695,13 +2694,15 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, rax);
} else if (proxy != NULL && proxy->var()->IsUnallocated()) {
} else if (call_type == Call::GLOBAL_CALL) {
// Call to a global variable. Push global object as receiver for the
// call IC lookup.
__ push(GlobalObjectOperand());
VariableProxy* proxy = callee->AsVariableProxy();
EmitCallWithIC(expr, proxy->name(), CONTEXTUAL);
} else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
// Call to a lookup slot (dynamically introduced variable).
VariableProxy* proxy = callee->AsVariableProxy();
Label slow, done;
{ PreservePositionScope scope(masm()->positions_recorder());
......@@ -2735,7 +2736,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// The receiver is either the global receiver or an object found by
// LoadContextSlot.
EmitCallWithStub(expr);
} else if (property != NULL) {
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
......@@ -2747,6 +2749,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitKeyedCallWithIC(expr, property->key());
}
} else {
ASSERT(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
......
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