| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 72   status_ = GENERATING; | 72   status_ = GENERATING; | 
| 73   CpuFeatures::Scope scope(SSE2); | 73   CpuFeatures::Scope scope(SSE2); | 
| 74 | 74 | 
| 75   CodeStub::GenerateFPStubs(); | 75   CodeStub::GenerateFPStubs(); | 
| 76 | 76 | 
| 77   // Open a frame scope to indicate that there is a frame on the stack.  The | 77   // Open a frame scope to indicate that there is a frame on the stack.  The | 
| 78   // MANUAL indicates that the scope shouldn't actually generate code to set up | 78   // MANUAL indicates that the scope shouldn't actually generate code to set up | 
| 79   // the frame (that is done in GeneratePrologue). | 79   // the frame (that is done in GeneratePrologue). | 
| 80   FrameScope frame_scope(masm_, StackFrame::MANUAL); | 80   FrameScope frame_scope(masm_, StackFrame::MANUAL); | 
| 81 | 81 | 
|  | 82   dynamic_frame_alignment_ = (chunk()->num_double_slots() > 2 && | 
|  | 83                               !chunk()->graph()->is_recursive()) || | 
|  | 84                              info()->osr_ast_id() != AstNode::kNoNumber; | 
|  | 85 | 
| 82   return GeneratePrologue() && | 86   return GeneratePrologue() && | 
| 83       GenerateBody() && | 87       GenerateBody() && | 
| 84       GenerateDeferredCode() && | 88       GenerateDeferredCode() && | 
| 85       GenerateSafepointTable(); | 89       GenerateSafepointTable(); | 
| 86 } | 90 } | 
| 87 | 91 | 
| 88 | 92 | 
| 89 void LCodeGen::FinishCode(Handle<Code> code) { | 93 void LCodeGen::FinishCode(Handle<Code> code) { | 
| 90   ASSERT(is_done()); | 94   ASSERT(is_done()); | 
| 91   code->set_stack_slots(GetStackSlotCount()); | 95   code->set_stack_slots(GetStackSlotCount()); | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 146     Label ok; | 150     Label ok; | 
| 147     __ test(ecx, Operand(ecx)); | 151     __ test(ecx, Operand(ecx)); | 
| 148     __ j(zero, &ok, Label::kNear); | 152     __ j(zero, &ok, Label::kNear); | 
| 149     // +1 for return address. | 153     // +1 for return address. | 
| 150     int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize; | 154     int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize; | 
| 151     __ mov(Operand(esp, receiver_offset), | 155     __ mov(Operand(esp, receiver_offset), | 
| 152            Immediate(isolate()->factory()->undefined_value())); | 156            Immediate(isolate()->factory()->undefined_value())); | 
| 153     __ bind(&ok); | 157     __ bind(&ok); | 
| 154   } | 158   } | 
| 155 | 159 | 
|  | 160   // Move state of dynamic frame alignment into edx. | 
|  | 161 | 
|  | 162   if (dynamic_frame_alignment_) { | 
|  | 163     __ mov(edx, Immediate(kNoAlignmentPadding)); | 
|  | 164 | 
|  | 165     Label do_not_pad, align_loop; | 
|  | 166     STATIC_ASSERT(kDoubleSize == 2 * kPointerSize); | 
|  | 167     // Align esp + 4 to a multiple of 2 * kPointerSize. | 
|  | 168     __ test(esp, Immediate(kPointerSize)); | 
|  | 169     __ j(not_zero, &do_not_pad, Label::kNear); | 
|  | 170     __ push(Immediate(0)); | 
|  | 171     __ mov(ebx, esp); | 
|  | 172     __ mov(edx, Immediate(kAlignmentPaddingPushed)); | 
|  | 173     // Copy arguments, receiver, and return address. | 
|  | 174     __ mov(ecx, Immediate(scope()->num_parameters() + 2)); | 
|  | 175 | 
|  | 176     __ bind(&align_loop); | 
|  | 177     __ mov(eax, Operand(ebx, 1 * kPointerSize)); | 
|  | 178     __ mov(Operand(ebx, 0), eax); | 
|  | 179     __ add(Operand(ebx), Immediate(kPointerSize)); | 
|  | 180     __ dec(ecx); | 
|  | 181     __ j(not_zero, &align_loop, Label::kNear); | 
|  | 182     __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue)); | 
|  | 183     __ bind(&do_not_pad); | 
|  | 184   } | 
|  | 185 | 
| 156   __ push(ebp);  // Caller's frame pointer. | 186   __ push(ebp);  // Caller's frame pointer. | 
| 157   __ mov(ebp, esp); | 187   __ mov(ebp, esp); | 
| 158   __ push(esi);  // Callee's context. | 188   __ push(esi);  // Callee's context. | 
| 159   __ push(edi);  // Callee's JS function. | 189   __ push(edi);  // Callee's JS function. | 
| 160 | 190 | 
|  | 191   if (dynamic_frame_alignment_ && FLAG_debug_code) { | 
|  | 192     __ test(esp, Immediate(kPointerSize)); | 
|  | 193     __ Assert(zero, "frame is expected to be aligned"); | 
|  | 194   } | 
|  | 195 | 
| 161   // Reserve space for the stack slots needed by the code. | 196   // Reserve space for the stack slots needed by the code. | 
| 162   int slots = GetStackSlotCount(); | 197   int slots = GetStackSlotCount(); | 
| 163   if (slots > 0) { | 198   ASSERT_GE(slots, 1); | 
| 164     if (FLAG_debug_code) { | 199   if (slots == 1 && !dynamic_frame_alignment_) { | 
| 165       __ mov(Operand(eax), Immediate(slots)); | 200     __ push(Immediate(kNoAlignmentPadding)); | 
| 166       Label loop; | 201   } else if (FLAG_debug_code) { | 
| 167       __ bind(&loop); | 202     __ mov(Operand(eax), Immediate(slots)); | 
| 168       __ push(Immediate(kSlotsZapValue)); | 203     Label loop; | 
| 169       __ dec(eax); | 204     __ bind(&loop); | 
| 170       __ j(not_zero, &loop); | 205     __ push(Immediate(kSlotsZapValue)); | 
| 171     } else { | 206     __ dec(eax); | 
| 172       __ sub(Operand(esp), Immediate(slots * kPointerSize)); | 207     __ j(not_zero, &loop); | 
|  | 208   } else { | 
|  | 209     __ sub(Operand(esp), Immediate(slots * kPointerSize)); | 
| 173 #ifdef _MSC_VER | 210 #ifdef _MSC_VER | 
| 174       // On windows, you may not access the stack more than one page below | 211     // On windows, you may not access the stack more than one page below | 
| 175       // the most recently mapped page. To make the allocated area randomly | 212     // the most recently mapped page. To make the allocated area randomly | 
| 176       // accessible, we write to each page in turn (the value is irrelevant). | 213     // accessible, we write to each page in turn (the value is irrelevant). | 
| 177       const int kPageSize = 4 * KB; | 214     const int kPageSize = 4 * KB; | 
| 178       for (int offset = slots * kPointerSize - kPageSize; | 215     for (int offset = slots * kPointerSize - kPageSize; | 
| 179            offset > 0; | 216          offset > 0; | 
| 180            offset -= kPageSize) { | 217          offset -= kPageSize) { | 
| 181         __ mov(Operand(esp, offset), eax); | 218       __ mov(Operand(esp, offset), eax); | 
| 182       } | 219     } | 
| 183 #endif | 220 #endif | 
| 184     } | 221   } | 
|  | 222 | 
|  | 223   // Store dynamic frame alignment state in the first local. | 
|  | 224   if (dynamic_frame_alignment_) { | 
|  | 225     __ mov(Operand(ebp, JavaScriptFrameConstants::kDynamicAlignmentStateOffset), | 
|  | 226            edx); | 
| 185   } | 227   } | 
| 186 | 228 | 
| 187   // Possibly allocate a local context. | 229   // Possibly allocate a local context. | 
| 188   int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 230   int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 
| 189   if (heap_slots > 0) { | 231   if (heap_slots > 0) { | 
| 190     Comment(";;; Allocate local context"); | 232     Comment(";;; Allocate local context"); | 
| 191     // Argument to NewContext is the function, which is still in edi. | 233     // Argument to NewContext is the function, which is still in edi. | 
| 192     __ push(edi); | 234     __ push(edi); | 
| 193     if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 235     if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 
| 194       FastNewContextStub stub(heap_slots); | 236       FastNewContextStub stub(heap_slots); | 
| (...skipping 1896 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2091 void LCodeGen::DoReturn(LReturn* instr) { | 2133 void LCodeGen::DoReturn(LReturn* instr) { | 
| 2092   if (FLAG_trace) { | 2134   if (FLAG_trace) { | 
| 2093     // Preserve the return value on the stack and rely on the runtime call | 2135     // Preserve the return value on the stack and rely on the runtime call | 
| 2094     // to return the value in the same register.  We're leaving the code | 2136     // to return the value in the same register.  We're leaving the code | 
| 2095     // managed by the register allocator and tearing down the frame, it's | 2137     // managed by the register allocator and tearing down the frame, it's | 
| 2096     // safe to write to the context register. | 2138     // safe to write to the context register. | 
| 2097     __ push(eax); | 2139     __ push(eax); | 
| 2098     __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2140     __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| 2099     __ CallRuntime(Runtime::kTraceExit, 1); | 2141     __ CallRuntime(Runtime::kTraceExit, 1); | 
| 2100   } | 2142   } | 
|  | 2143   if (dynamic_frame_alignment_) { | 
|  | 2144     // Fetch the state of the dynamic frame alignment. | 
|  | 2145     __ mov(edx, Operand(ebp, | 
|  | 2146       JavaScriptFrameConstants::kDynamicAlignmentStateOffset)); | 
|  | 2147   } | 
| 2101   __ mov(esp, ebp); | 2148   __ mov(esp, ebp); | 
| 2102   __ pop(ebp); | 2149   __ pop(ebp); | 
|  | 2150   if (dynamic_frame_alignment_) { | 
|  | 2151     Label no_padding; | 
|  | 2152     __ cmp(edx, Immediate(kNoAlignmentPadding)); | 
|  | 2153     __ j(equal, &no_padding); | 
|  | 2154     if (FLAG_debug_code) { | 
|  | 2155       __ cmp(Operand(esp, (GetParameterCount() + 2) * kPointerSize), | 
|  | 2156              Immediate(kAlignmentZapValue)); | 
|  | 2157       __ Assert(equal, "expected alignment marker"); | 
|  | 2158     } | 
|  | 2159     __ Ret((GetParameterCount() + 2) * kPointerSize, ecx); | 
|  | 2160     __ bind(&no_padding); | 
|  | 2161   } | 
| 2103   __ Ret((GetParameterCount() + 1) * kPointerSize, ecx); | 2162   __ Ret((GetParameterCount() + 1) * kPointerSize, ecx); | 
| 2104 } | 2163 } | 
| 2105 | 2164 | 
| 2106 | 2165 | 
| 2107 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { | 2166 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { | 
| 2108   Register result = ToRegister(instr->result()); | 2167   Register result = ToRegister(instr->result()); | 
| 2109   __ mov(result, Operand::Cell(instr->hydrogen()->cell())); | 2168   __ mov(result, Operand::Cell(instr->hydrogen()->cell())); | 
| 2110   if (instr->hydrogen()->RequiresHoleCheck()) { | 2169   if (instr->hydrogen()->RequiresHoleCheck()) { | 
| 2111     __ cmp(result, factory()->the_hole_value()); | 2170     __ cmp(result, factory()->the_hole_value()); | 
| 2112     DeoptimizeIf(equal, instr->environment()); | 2171     DeoptimizeIf(equal, instr->environment()); | 
| (...skipping 2992 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5105                               FixedArray::kHeaderSize - kPointerSize)); | 5164                               FixedArray::kHeaderSize - kPointerSize)); | 
| 5106   __ bind(&done); | 5165   __ bind(&done); | 
| 5107 } | 5166 } | 
| 5108 | 5167 | 
| 5109 | 5168 | 
| 5110 #undef __ | 5169 #undef __ | 
| 5111 | 5170 | 
| 5112 } }  // namespace v8::internal | 5171 } }  // namespace v8::internal | 
| 5113 | 5172 | 
| 5114 #endif  // V8_TARGET_ARCH_IA32 | 5173 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|