| Index: src/ia32/full-codegen-ia32.cc
|
| diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
|
| index 919cca23e047b1ec535f08d367a057f89f9dc277..785af974d56561846daac3d60b25305b3e1510ab 100644
|
| --- a/src/ia32/full-codegen-ia32.cc
|
| +++ b/src/ia32/full-codegen-ia32.cc
|
| @@ -2061,7 +2061,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
| +void FullCodeGenerator::EmitCallWithIC(CallBase* expr,
|
| Handle<Object> name,
|
| RelocInfo::Mode mode) {
|
| // Code common for calls using the IC.
|
| @@ -2085,8 +2085,9 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
| - Expression* key) {
|
| +void FullCodeGenerator::EmitKeyedCallWithIC(CallBase* expr,
|
| + Expression* key,
|
| + RelocInfo::Mode mode) {
|
| // Load the key.
|
| VisitForAccumulatorValue(key);
|
|
|
| @@ -2107,9 +2108,9 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
| // Record source position of the IC call.
|
| SetSourcePosition(expr->position());
|
| Handle<Code> ic =
|
| - isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
|
| + isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, mode);
|
| __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
|
| - __ call(ic, RelocInfo::CODE_TARGET, expr->id());
|
| + __ call(ic, mode, expr->id());
|
| RecordJSReturnSite(expr);
|
| // Restore context register.
|
| __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
| @@ -2277,7 +2278,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
| property->key()->AsLiteral()->handle(),
|
| RelocInfo::CODE_TARGET);
|
| } else {
|
| - EmitKeyedCallWithIC(expr, property->key());
|
| + EmitKeyedCallWithIC(expr, property->key(), RelocInfo::CODE_TARGET);
|
| }
|
|
|
| } else {
|
| @@ -2300,35 +2301,60 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
|
|
|
|
| void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
| +#ifdef DEBUG
|
| + // We want to verify that RecordJSReturnSite gets called on all paths
|
| + // through this function. Avoid early returns.
|
| + expr->return_is_recorded_ = false;
|
| +#endif
|
| +
|
| Comment cmnt(masm_, "[ CallNew");
|
| + Expression* callee = expr->expression();
|
| + Property* property = callee->AsProperty();
|
| +
|
| // According to ECMA-262, section 11.2.2, page 44, the function
|
| // expression in new calls must be evaluated before the
|
| // arguments.
|
|
|
| - // Push constructor on the stack. If it's not a function it's used as
|
| - // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
|
| - // ignored.
|
| - VisitForStackValue(expr->expression());
|
| + if (property != NULL) {
|
| + // TODO(mstarzinger): This bailout is only needed because we do not use
|
| + // type feedback in Crankshaft yet.
|
| + PrepareForBailout(callee, TOS_REG);
|
| + { PreservePositionScope scope(masm()->positions_recorder());
|
| + VisitForStackValue(property->obj());
|
| + }
|
| + if (property->key()->IsPropertyName()) {
|
| + EmitCallWithIC(expr,
|
| + property->key()->AsLiteral()->handle(),
|
| + RelocInfo::CONSTRUCT_CALL);
|
| + } else {
|
| + EmitKeyedCallWithIC(expr, property->key(), RelocInfo::CONSTRUCT_CALL);
|
| + }
|
|
|
| - // Push the arguments ("left-to-right") on the stack.
|
| - ZoneList<Expression*>* args = expr->arguments();
|
| - int arg_count = args->length();
|
| - for (int i = 0; i < arg_count; i++) {
|
| - VisitForStackValue(args->at(i));
|
| - }
|
| + } else {
|
| + // Push constructor on the stack. If it's not a function it's used as
|
| + // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
|
| + // ignored.
|
| + VisitForStackValue(callee);
|
|
|
| - // Call the construct call builtin that handles allocation and
|
| - // constructor invocation.
|
| - SetSourcePosition(expr->position());
|
| + // Push the arguments ("left-to-right") on the stack.
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| + int arg_count = args->length();
|
| + for (int i = 0; i < arg_count; i++) {
|
| + VisitForStackValue(args->at(i));
|
| + }
|
|
|
| - // Load function and argument count into edi and eax.
|
| - __ SafeSet(eax, Immediate(arg_count));
|
| - __ mov(edi, Operand(esp, arg_count * kPointerSize));
|
| + // Call the construct call builtin that handles allocation and
|
| + // constructor invocation.
|
| + SetSourcePosition(expr->position());
|
|
|
| - Handle<Code> construct_builtin =
|
| - isolate()->builtins()->JSConstructCall();
|
| - __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
|
| - context()->Plug(eax);
|
| + // Load function and argument count into edi and eax.
|
| + __ SafeSet(eax, Immediate(arg_count));
|
| + __ mov(edi, Operand(esp, arg_count * kPointerSize));
|
| +
|
| + Handle<Code> construct_builtin = isolate()->builtins()->JSConstructCall();
|
| + __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
|
| + context()->Plug(eax);
|
| + }
|
| }
|
|
|
|
|
|
|