OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "ia32/lithium-codegen-ia32.h" | 9 #include "ia32/lithium-codegen-ia32.h" |
10 #include "ic.h" | 10 #include "ic.h" |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 } | 247 } |
248 } | 248 } |
249 | 249 |
250 if (info()->saves_caller_doubles()) SaveCallerDoubles(); | 250 if (info()->saves_caller_doubles()) SaveCallerDoubles(); |
251 } | 251 } |
252 | 252 |
253 // Possibly allocate a local context. | 253 // Possibly allocate a local context. |
254 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 254 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
255 if (heap_slots > 0) { | 255 if (heap_slots > 0) { |
256 Comment(";;; Allocate local context"); | 256 Comment(";;; Allocate local context"); |
| 257 bool need_write_barrier = true; |
257 // Argument to NewContext is the function, which is still in edi. | 258 // Argument to NewContext is the function, which is still in edi. |
258 if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 259 if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
259 FastNewContextStub stub(isolate(), heap_slots); | 260 FastNewContextStub stub(isolate(), heap_slots); |
260 __ CallStub(&stub); | 261 __ CallStub(&stub); |
| 262 // Result of FastNewContextStub is always in new space. |
| 263 need_write_barrier = false; |
261 } else { | 264 } else { |
262 __ push(edi); | 265 __ push(edi); |
263 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); | 266 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
264 } | 267 } |
265 RecordSafepoint(Safepoint::kNoLazyDeopt); | 268 RecordSafepoint(Safepoint::kNoLazyDeopt); |
266 // Context is returned in eax. It replaces the context passed to us. | 269 // Context is returned in eax. It replaces the context passed to us. |
267 // It's saved in the stack and kept live in esi. | 270 // It's saved in the stack and kept live in esi. |
268 __ mov(esi, eax); | 271 __ mov(esi, eax); |
269 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); | 272 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); |
270 | 273 |
271 // Copy parameters into context if necessary. | 274 // Copy parameters into context if necessary. |
272 int num_parameters = scope()->num_parameters(); | 275 int num_parameters = scope()->num_parameters(); |
273 for (int i = 0; i < num_parameters; i++) { | 276 for (int i = 0; i < num_parameters; i++) { |
274 Variable* var = scope()->parameter(i); | 277 Variable* var = scope()->parameter(i); |
275 if (var->IsContextSlot()) { | 278 if (var->IsContextSlot()) { |
276 int parameter_offset = StandardFrameConstants::kCallerSPOffset + | 279 int parameter_offset = StandardFrameConstants::kCallerSPOffset + |
277 (num_parameters - 1 - i) * kPointerSize; | 280 (num_parameters - 1 - i) * kPointerSize; |
278 // Load parameter from stack. | 281 // Load parameter from stack. |
279 __ mov(eax, Operand(ebp, parameter_offset)); | 282 __ mov(eax, Operand(ebp, parameter_offset)); |
280 // Store it in the context. | 283 // Store it in the context. |
281 int context_offset = Context::SlotOffset(var->index()); | 284 int context_offset = Context::SlotOffset(var->index()); |
282 __ mov(Operand(esi, context_offset), eax); | 285 __ mov(Operand(esi, context_offset), eax); |
283 // Update the write barrier. This clobbers eax and ebx. | 286 // Update the write barrier. This clobbers eax and ebx. |
284 __ RecordWriteContextSlot(esi, | 287 if (need_write_barrier) { |
285 context_offset, | 288 __ RecordWriteContextSlot(esi, |
286 eax, | 289 context_offset, |
287 ebx, | 290 eax, |
288 kDontSaveFPRegs); | 291 ebx, |
| 292 kDontSaveFPRegs); |
| 293 } else if (FLAG_debug_code) { |
| 294 Label done; |
| 295 __ JumpIfInNewSpace(esi, eax, &done, Label::kNear); |
| 296 __ Abort(kExpectedNewSpaceObject); |
| 297 __ bind(&done); |
| 298 } |
289 } | 299 } |
290 } | 300 } |
291 Comment(";;; End allocate local context"); | 301 Comment(";;; End allocate local context"); |
292 } | 302 } |
293 | 303 |
294 // Trace the call. | 304 // Trace the call. |
295 if (FLAG_trace && info()->IsOptimizing()) { | 305 if (FLAG_trace && info()->IsOptimizing()) { |
296 // We have not executed any compiled code yet, so esi still holds the | 306 // We have not executed any compiled code yet, so esi still holds the |
297 // incoming context. | 307 // incoming context. |
298 __ CallRuntime(Runtime::kTraceEnter, 0); | 308 __ CallRuntime(Runtime::kTraceEnter, 0); |
(...skipping 5371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5670 __ bind(deferred->exit()); | 5680 __ bind(deferred->exit()); |
5671 __ bind(&done); | 5681 __ bind(&done); |
5672 } | 5682 } |
5673 | 5683 |
5674 | 5684 |
5675 #undef __ | 5685 #undef __ |
5676 | 5686 |
5677 } } // namespace v8::internal | 5687 } } // namespace v8::internal |
5678 | 5688 |
5679 #endif // V8_TARGET_ARCH_IA32 | 5689 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |