| Index: src/ia32/builtins-ia32.cc
|
| ===================================================================
|
| --- src/ia32/builtins-ia32.cc (revision 8110)
|
| +++ src/ia32/builtins-ia32.cc (working copy)
|
| @@ -114,7 +114,8 @@
|
| ASSERT(!is_api_function || !count_constructions);
|
|
|
| // Enter a construct frame.
|
| - __ EnterConstructFrame();
|
| +{
|
| + FrameScope scope(masm, StackFrame::CONSTRUCT);
|
|
|
| // Store a smi-tagged arguments count on the stack.
|
| __ SmiTag(eax);
|
| @@ -123,8 +124,8 @@
|
| // Push the function to invoke on the stack.
|
| __ push(edi);
|
|
|
| - // Try to allocate the object without transitioning into C code. If any of the
|
| - // preconditions is not met, the code bails out to the runtime call.
|
| + // Try to allocate the object without transitioning into C code. If any of
|
| + // the preconditions is not met, the code bails out to the runtime call.
|
| Label rt_call, allocated;
|
| if (FLAG_inline_new) {
|
| Label undo_allocation;
|
| @@ -147,9 +148,9 @@
|
| __ CmpObjectType(eax, MAP_TYPE, ebx);
|
| __ j(not_equal, &rt_call);
|
|
|
| - // Check that the constructor is not constructing a JSFunction (see comments
|
| - // in Runtime_NewObject in runtime.cc). In which case the initial map's
|
| - // instance type would be JS_FUNCTION_TYPE.
|
| + // Check that the constructor is not constructing a JSFunction (see
|
| + // comments in Runtime_NewObject in runtime.cc). In which case the initial
|
| + // map's instance type would be JS_FUNCTION_TYPE.
|
| // edi: constructor
|
| // eax: initial map
|
| __ CmpInstanceType(eax, JS_FUNCTION_TYPE);
|
| @@ -159,7 +160,8 @@
|
| Label allocate;
|
| // Decrease generous allocation count.
|
| __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
| - __ dec_b(FieldOperand(ecx, SharedFunctionInfo::kConstructionCountOffset));
|
| + __ dec_b(FieldOperand(ecx,
|
| + SharedFunctionInfo::kConstructionCountOffset));
|
| __ j(not_zero, &allocate);
|
|
|
| __ push(eax);
|
| @@ -180,7 +182,12 @@
|
| // eax: initial map
|
| __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset));
|
| __ shl(edi, kPointerSizeLog2);
|
| - __ AllocateInNewSpace(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS);
|
| + __ AllocateInNewSpace(edi,
|
| + ebx,
|
| + edi,
|
| + no_reg,
|
| + &rt_call,
|
| + NO_ALLOCATION_FLAGS);
|
| // Allocated the JSObject, now initialize the fields.
|
| // eax: initial map
|
| // ebx: JSObject
|
| @@ -211,10 +218,10 @@
|
| __ j(less, &loop);
|
| }
|
|
|
| - // Add the object tag to make the JSObject real, so that we can continue and
|
| - // jump into the continuation code at any time from now on. Any failures
|
| - // need to undo the allocation, so that the heap is in a consistent state
|
| - // and verifiable.
|
| + // Add the object tag to make the JSObject real, so that we can continue
|
| + // and jump into the continuation code at any time from now on. Any
|
| + // failures need to undo the allocation, so that the heap is in a
|
| + // consistent state and verifiable.
|
| // eax: initial map
|
| // ebx: JSObject
|
| // edi: start of next object
|
| @@ -227,7 +234,8 @@
|
| // edi: start of next object
|
| // Calculate the total number of properties described by the map.
|
| __ movzx_b(edx, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset));
|
| - __ movzx_b(ecx, FieldOperand(eax, Map::kPreAllocatedPropertyFieldsOffset));
|
| + __ movzx_b(ecx,
|
| + FieldOperand(eax, Map::kPreAllocatedPropertyFieldsOffset));
|
| __ add(edx, Operand(ecx));
|
| // Calculate unused properties past the end of the in-object properties.
|
| __ movzx_b(ecx, FieldOperand(eax, Map::kInObjectPropertiesOffset));
|
| @@ -373,8 +381,10 @@
|
| // Restore the arguments count and leave the construct frame.
|
| __ bind(&exit);
|
| __ mov(ebx, Operand(esp, kPointerSize)); // get arguments count
|
| - __ LeaveConstructFrame();
|
|
|
| + // Leave construct frame.
|
| +}
|
| +
|
| // Remove caller arguments from the stack and return.
|
| ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
|
| __ pop(ecx);
|
| @@ -402,11 +412,11 @@
|
|
|
| static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
|
| bool is_construct) {
|
| - // Clear the context before we push it when entering the JS frame.
|
| + // Clear the context before we push it when entering the internal frame.
|
| __ Set(esi, Immediate(0));
|
|
|
| - // Enter an internal frame.
|
| - __ EnterInternalFrame();
|
| +{
|
| + FrameScope scope(masm, StackFrame::INTERNAL);
|
|
|
| // Load the previous frame pointer (ebx) to access C arguments
|
| __ mov(ebx, Operand(ebp, 0));
|
| @@ -436,7 +446,8 @@
|
| __ j(not_equal, &loop);
|
|
|
| // Get the function from the stack and call it.
|
| - __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize)); // +1 ~ receiver
|
| + // kPointerSize for the receiver.
|
| + __ mov(edi, Operand(esp, eax, times_4, kPointerSize));
|
|
|
| // Invoke the code.
|
| if (is_construct) {
|
| @@ -448,12 +459,12 @@
|
| NullCallWrapper(), CALL_AS_METHOD);
|
| }
|
|
|
| - // Exit the JS frame. Notice that this also removes the empty
|
| + // Exit the internal frame. Notice that this also removes the empty.
|
| // context and the function left on the stack by the code
|
| // invocation.
|
| - __ LeaveInternalFrame();
|
| - __ ret(1 * kPointerSize); // remove receiver
|
| }
|
| + __ ret(kPointerSize); // Remove receiver.
|
| +}
|
|
|
|
|
| void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
|
| @@ -467,8 +478,8 @@
|
|
|
|
|
| void Builtins::Generate_LazyCompile(MacroAssembler* masm) {
|
| - // Enter an internal frame.
|
| - __ EnterInternalFrame();
|
| +{
|
| + FrameScope scope(masm, StackFrame::INTERNAL);
|
|
|
| // Push a copy of the function.
|
| __ push(edi);
|
| @@ -483,8 +494,8 @@
|
| // Restore receiver.
|
| __ pop(edi);
|
|
|
| - // Tear down temporary frame.
|
| - __ LeaveInternalFrame();
|
| + // Tear down internal frame.
|
| +}
|
|
|
| // Do a tail-call of the compiled function.
|
| __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
|
| @@ -493,8 +504,8 @@
|
|
|
|
|
| void Builtins::Generate_LazyRecompile(MacroAssembler* masm) {
|
| - // Enter an internal frame.
|
| - __ EnterInternalFrame();
|
| +{
|
| + FrameScope scope(masm, StackFrame::INTERNAL);
|
|
|
| // Push a copy of the function onto the stack.
|
| __ push(edi);
|
| @@ -509,8 +520,8 @@
|
| // Restore receiver.
|
| __ pop(edi);
|
|
|
| - // Tear down temporary frame.
|
| - __ LeaveInternalFrame();
|
| + // Tear down internal frame.
|
| +}
|
|
|
| // Do a tail-call of the compiled function.
|
| __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
|
| @@ -520,15 +531,15 @@
|
|
|
| static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
|
| Deoptimizer::BailoutType type) {
|
| - // Enter an internal frame.
|
| - __ EnterInternalFrame();
|
| +{
|
| + FrameScope scope(masm, StackFrame::INTERNAL);
|
|
|
| // Pass the function and deoptimization type to the runtime system.
|
| __ push(Immediate(Smi::FromInt(static_cast<int>(type))));
|
| __ CallRuntime(Runtime::kNotifyDeoptimized, 1);
|
|
|
| - // Tear down temporary frame.
|
| - __ LeaveInternalFrame();
|
| + // Tear down internal frame.
|
| +}
|
|
|
| // Get the full codegen state from the stack and untag it.
|
| __ mov(ecx, Operand(esp, 1 * kPointerSize));
|
| @@ -569,9 +580,10 @@
|
| // the registers without worrying about which of them contain
|
| // pointers. This seems a bit fragile.
|
| __ pushad();
|
| - __ EnterInternalFrame();
|
| - __ CallRuntime(Runtime::kNotifyOSR, 0);
|
| - __ LeaveInternalFrame();
|
| + {
|
| + FrameScope scope(masm, StackFrame::INTERNAL);
|
| + __ CallRuntime(Runtime::kNotifyOSR, 0);
|
| + }
|
| __ popad();
|
| __ ret(0);
|
| }
|
| @@ -636,7 +648,9 @@
|
| __ j(above_equal, &shift_arguments);
|
|
|
| __ bind(&convert_to_object);
|
| - __ EnterInternalFrame(); // In order to preserve argument count.
|
| +
|
| + { // In order to preserve argument count.
|
| + FrameScope scope(masm, StackFrame::INTERNAL);
|
| __ SmiTag(eax);
|
| __ push(eax);
|
|
|
| @@ -646,7 +660,8 @@
|
|
|
| __ pop(eax);
|
| __ SmiUntag(eax);
|
| - __ LeaveInternalFrame();
|
| + }
|
| +
|
| // Restore the function to edi.
|
| __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize));
|
| __ jmp(&patch_receiver);
|
| @@ -723,7 +738,8 @@
|
|
|
|
|
| void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
|
| - __ EnterInternalFrame();
|
| +{
|
| + FrameScope scope(masm, StackFrame::INTERNAL);
|
|
|
| __ push(Operand(ebp, 4 * kPointerSize)); // push this
|
| __ push(Operand(ebp, 2 * kPointerSize)); // push arguments
|
| @@ -851,7 +867,8 @@
|
| __ InvokeFunction(edi, actual, CALL_FUNCTION,
|
| NullCallWrapper(), CALL_AS_METHOD);
|
|
|
| - __ LeaveInternalFrame();
|
| + // Leave the internal frame.
|
| +}
|
| __ ret(3 * kPointerSize); // remove this, receiver, and arguments
|
| }
|
|
|
| @@ -1403,12 +1420,13 @@
|
| // Invoke the conversion builtin and put the result into ebx.
|
| __ bind(&convert_argument);
|
| __ IncrementCounter(counters->string_ctor_conversions(), 1);
|
| - __ EnterInternalFrame();
|
| +{
|
| + FrameScope scope(masm, StackFrame::INTERNAL);
|
| __ push(edi); // Preserve the function.
|
| __ push(eax);
|
| __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
|
| __ pop(edi);
|
| - __ LeaveInternalFrame();
|
| +}
|
| __ mov(ebx, eax);
|
| __ jmp(&argument_is_string);
|
|
|
| @@ -1425,10 +1443,11 @@
|
| // create a string wrapper.
|
| __ bind(&gc_required);
|
| __ IncrementCounter(counters->string_ctor_gc_required(), 1);
|
| - __ EnterInternalFrame();
|
| +{
|
| + FrameScope scope(masm, StackFrame::INTERNAL);
|
| __ push(ebx);
|
| __ CallRuntime(Runtime::kNewStringWrapper, 1);
|
| - __ LeaveInternalFrame();
|
| +}
|
| __ ret(0);
|
| }
|
|
|
| @@ -1553,7 +1572,7 @@
|
|
|
| void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
|
| CpuFeatures::TryForceFeatureScope scope(SSE2);
|
| - if (!CpuFeatures::IsSupported(SSE2)) {
|
| + if (!CpuFeatures::IsSupported(SSE2) && FLAG_debug_code) {
|
| __ Abort("Unreachable code: Cannot optimize without SSE2 support.");
|
| return;
|
| }
|
| @@ -1580,10 +1599,11 @@
|
|
|
| // Pass the function to optimize as the argument to the on-stack
|
| // replacement runtime function.
|
| - __ EnterInternalFrame();
|
| +{
|
| + FrameScope scope(masm, StackFrame::INTERNAL);
|
| __ push(eax);
|
| __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
|
| - __ LeaveInternalFrame();
|
| +}
|
|
|
| // If the result was -1 it means that we couldn't optimize the
|
| // function. Just return and continue in the unoptimized version.
|
| @@ -1602,7 +1622,9 @@
|
| __ j(above_equal, &ok, Label::kNear);
|
| StackCheckStub stub;
|
| __ TailCallStub(&stub);
|
| - __ Abort("Unreachable code: returned from tail call.");
|
| + if (FLAG_debug_code) {
|
| + __ Abort("Unreachable code: returned from tail call.");
|
| + }
|
| __ bind(&ok);
|
| __ ret(0);
|
|
|
|
|