| Index: src/ia32/stub-cache-ia32.cc
|
| diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
|
| index d339da92c489141f1fb9baf8a1acdef69d613c54..354c2fdcb0c3c7f386a71fe32d6e8f2d2c9f16bb 100644
|
| --- a/src/ia32/stub-cache-ia32.cc
|
| +++ b/src/ia32/stub-cache-ia32.cc
|
| @@ -329,28 +329,32 @@ void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
|
| Register receiver,
|
| Register scratch1,
|
| Register scratch2,
|
| - Label* miss) {
|
| + Label* miss,
|
| + bool support_wrappers) {
|
| Label check_wrapper;
|
|
|
| // Check if the object is a string leaving the instance type in the
|
| // scratch register.
|
| - GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper);
|
| + GenerateStringCheck(masm, receiver, scratch1, miss,
|
| + support_wrappers ? &check_wrapper : miss);
|
|
|
| // Load length from the string and convert to a smi.
|
| __ mov(eax, FieldOperand(receiver, String::kLengthOffset));
|
| __ ret(0);
|
|
|
| - // Check if the object is a JSValue wrapper.
|
| - __ bind(&check_wrapper);
|
| - __ cmp(scratch1, JS_VALUE_TYPE);
|
| - __ j(not_equal, miss);
|
| + if (support_wrappers) {
|
| + // Check if the object is a JSValue wrapper.
|
| + __ bind(&check_wrapper);
|
| + __ cmp(scratch1, JS_VALUE_TYPE);
|
| + __ j(not_equal, miss);
|
|
|
| - // Check if the wrapped value is a string and load the length
|
| - // directly if it is.
|
| - __ mov(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
|
| - GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
|
| - __ mov(eax, FieldOperand(scratch2, String::kLengthOffset));
|
| - __ ret(0);
|
| + // Check if the wrapped value is a string and load the length
|
| + // directly if it is.
|
| + __ mov(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
|
| + GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
|
| + __ mov(eax, FieldOperand(scratch2, String::kLengthOffset));
|
| + __ ret(0);
|
| + }
|
| }
|
|
|
|
|
| @@ -458,54 +462,48 @@ static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
|
| // Generates call to API function.
|
| static void GenerateFastApiCall(MacroAssembler* masm,
|
| const CallOptimization& optimization,
|
| - int argc,
|
| - bool restore_context) {
|
| + int argc) {
|
| // ----------- S t a t e -------------
|
| // -- esp[0] : return address
|
| - // -- esp[4] : context
|
| - // -- esp[8] : object passing the type check
|
| + // -- esp[4] : object passing the type check
|
| // (last fast api call extra argument,
|
| // set by CheckPrototypes)
|
| - // -- esp[12] : api function
|
| + // -- esp[8] : api function
|
| // (first fast api call extra argument)
|
| - // -- esp[16] : api call data
|
| - // -- esp[20] : isolate
|
| - // -- esp[24] : ReturnValue default value
|
| - // -- esp[28] : ReturnValue
|
| - // -- esp[32] : last argument
|
| + // -- esp[12] : api call data
|
| + // -- esp[16] : isolate
|
| + // -- esp[20] : ReturnValue default value
|
| + // -- esp[24] : ReturnValue
|
| + // -- esp[28] : last argument
|
| // -- ...
|
| - // -- esp[(argc + 7) * 4] : first argument
|
| - // -- esp[(argc + 8) * 4] : receiver
|
| + // -- esp[(argc + 6) * 4] : first argument
|
| + // -- esp[(argc + 7) * 4] : receiver
|
| // -----------------------------------
|
| -
|
| - // Save calling context.
|
| - __ mov(Operand(esp, kPointerSize), esi);
|
| -
|
| // Get the function and setup the context.
|
| Handle<JSFunction> function = optimization.constant_function();
|
| __ LoadHeapObject(edi, function);
|
| __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
|
|
|
| // Pass the additional arguments.
|
| - __ mov(Operand(esp, 3 * kPointerSize), edi);
|
| + __ mov(Operand(esp, 2 * kPointerSize), edi);
|
| Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
|
| Handle<Object> call_data(api_call_info->data(), masm->isolate());
|
| if (masm->isolate()->heap()->InNewSpace(*call_data)) {
|
| __ mov(ecx, api_call_info);
|
| __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
|
| - __ mov(Operand(esp, 4 * kPointerSize), ebx);
|
| + __ mov(Operand(esp, 3 * kPointerSize), ebx);
|
| } else {
|
| - __ mov(Operand(esp, 4 * kPointerSize), Immediate(call_data));
|
| + __ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data));
|
| }
|
| - __ mov(Operand(esp, 5 * kPointerSize),
|
| + __ mov(Operand(esp, 4 * kPointerSize),
|
| Immediate(reinterpret_cast<int>(masm->isolate())));
|
| - __ mov(Operand(esp, 6 * kPointerSize),
|
| + __ mov(Operand(esp, 5 * kPointerSize),
|
| masm->isolate()->factory()->undefined_value());
|
| - __ mov(Operand(esp, 7 * kPointerSize),
|
| + __ mov(Operand(esp, 6 * kPointerSize),
|
| masm->isolate()->factory()->undefined_value());
|
|
|
| // Prepare arguments.
|
| - STATIC_ASSERT(kFastApiCallArguments == 7);
|
| + STATIC_ASSERT(kFastApiCallArguments == 6);
|
| __ lea(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
|
|
|
|
|
| @@ -539,16 +537,11 @@ static void GenerateFastApiCall(MacroAssembler* masm,
|
|
|
| Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
|
|
|
| - Operand context_restore_operand(ebp, 2 * kPointerSize);
|
| - Operand return_value_operand(
|
| - ebp, (kFastApiCallArguments + 1) * kPointerSize);
|
| __ CallApiFunctionAndReturn(function_address,
|
| thunk_address,
|
| ApiParameterOperand(1),
|
| argc + kFastApiCallArguments + 1,
|
| - return_value_operand,
|
| - restore_context ?
|
| - &context_restore_operand : NULL);
|
| + kFastApiCallArguments + 1);
|
| }
|
|
|
|
|
| @@ -563,8 +556,6 @@ static void GenerateFastApiCall(MacroAssembler* masm,
|
| ASSERT(!receiver.is(scratch));
|
|
|
| const int stack_space = kFastApiCallArguments + argc + 1;
|
| - const int kHolderIndex = kFastApiCallArguments +
|
| - FunctionCallbackArguments::kHolderIndex;
|
| // Copy return value.
|
| __ mov(scratch, Operand(esp, 0));
|
| // Assign stack space for the call arguments.
|
| @@ -572,7 +563,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
|
| // Move the return address on top of the stack.
|
| __ mov(Operand(esp, 0), scratch);
|
| // Write holder to stack frame.
|
| - __ mov(Operand(esp, kHolderIndex * kPointerSize), receiver);
|
| + __ mov(Operand(esp, 1 * kPointerSize), receiver);
|
| // Write receiver to stack frame.
|
| int index = stack_space;
|
| __ mov(Operand(esp, index-- * kPointerSize), receiver);
|
| @@ -583,7 +574,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
|
| __ mov(Operand(esp, index-- * kPointerSize), values[i]);
|
| }
|
|
|
| - GenerateFastApiCall(masm, optimization, argc, true);
|
| + GenerateFastApiCall(masm, optimization, argc);
|
| }
|
|
|
|
|
| @@ -697,7 +688,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
|
|
| // Invoke function.
|
| if (can_do_fast_api_call) {
|
| - GenerateFastApiCall(masm, optimization, arguments_.immediate(), false);
|
| + GenerateFastApiCall(masm, optimization, arguments_.immediate());
|
| } else {
|
| CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
|
| ? CALL_AS_FUNCTION
|
| @@ -871,7 +862,7 @@ void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
|
| __ SmiUntag(value_reg);
|
| if (CpuFeatures::IsSupported(SSE2)) {
|
| CpuFeatureScope use_sse2(masm, SSE2);
|
| - __ Cvtsi2sd(xmm0, value_reg);
|
| + __ cvtsi2sd(xmm0, value_reg);
|
| } else {
|
| __ push(value_reg);
|
| __ fild_s(Operand(esp, 0));
|
| @@ -1050,7 +1041,7 @@ void BaseStoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
|
| __ SmiUntag(value_reg);
|
| if (CpuFeatures::IsSupported(SSE2)) {
|
| CpuFeatureScope use_sse2(masm, SSE2);
|
| - __ Cvtsi2sd(xmm0, value_reg);
|
| + __ cvtsi2sd(xmm0, value_reg);
|
| } else {
|
| __ push(value_reg);
|
| __ fild_s(Operand(esp, 0));
|
| @@ -1169,8 +1160,6 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
|
| int save_at_depth,
|
| Label* miss,
|
| PrototypeCheckType check) {
|
| - const int kHolderIndex = kFastApiCallArguments +
|
| - FunctionCallbackArguments::kHolderIndex;
|
| // Make sure that the type feedback oracle harvests the receiver map.
|
| // TODO(svenpanne) Remove this hack when all ICs are reworked.
|
| __ mov(scratch1, Handle<Map>(object->map()));
|
| @@ -1187,7 +1176,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
|
| int depth = 0;
|
|
|
| if (save_at_depth == depth) {
|
| - __ mov(Operand(esp, kHolderIndex * kPointerSize), reg);
|
| + __ mov(Operand(esp, kPointerSize), reg);
|
| }
|
|
|
| // Traverse the prototype chain and check the maps in the prototype chain for
|
| @@ -1248,7 +1237,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
|
| }
|
|
|
| if (save_at_depth == depth) {
|
| - __ mov(Operand(esp, kHolderIndex * kPointerSize), reg);
|
| + __ mov(Operand(esp, kPointerSize), reg);
|
| }
|
|
|
| // Go to the next object in the prototype chain.
|
| @@ -1471,8 +1460,7 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
|
| thunk_address,
|
| ApiParameterOperand(2),
|
| kStackSpace,
|
| - Operand(ebp, 7 * kPointerSize),
|
| - NULL);
|
| + 7);
|
| }
|
|
|
|
|
| @@ -2635,7 +2623,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
|
|
|
| // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
|
| // duplicate of return address and will be overwritten.
|
| - GenerateFastApiCall(masm(), optimization, argc, false);
|
| + GenerateFastApiCall(masm(), optimization, argc);
|
|
|
| __ bind(&miss);
|
| __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
|
|
|