| 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 "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 } else { | 367 } else { |
| 368 DCHECK_EQ(0, x87_stack_.depth()); | 368 DCHECK_EQ(0, x87_stack_.depth()); |
| 369 } | 369 } |
| 370 } | 370 } |
| 371 __ VerifyX87StackDepth(x87_stack_.depth()); | 371 __ VerifyX87StackDepth(x87_stack_.depth()); |
| 372 } | 372 } |
| 373 } | 373 } |
| 374 | 374 |
| 375 | 375 |
| 376 bool LCodeGen::GenerateJumpTable() { | 376 bool LCodeGen::GenerateJumpTable() { |
| 377 if (!jump_table_.length()) return !is_aborted(); |
| 378 |
| 377 Label needs_frame; | 379 Label needs_frame; |
| 378 if (jump_table_.length() > 0) { | 380 Comment(";;; -------------------- Jump table --------------------"); |
| 379 Comment(";;; -------------------- Jump table --------------------"); | 381 |
| 380 } | |
| 381 for (int i = 0; i < jump_table_.length(); i++) { | 382 for (int i = 0; i < jump_table_.length(); i++) { |
| 382 Deoptimizer::JumpTableEntry* table_entry = &jump_table_[i]; | 383 Deoptimizer::JumpTableEntry* table_entry = &jump_table_[i]; |
| 383 __ bind(&table_entry->label); | 384 __ bind(&table_entry->label); |
| 384 Address entry = table_entry->address; | 385 Address entry = table_entry->address; |
| 385 DeoptComment(table_entry->deopt_info); | 386 DeoptComment(table_entry->deopt_info); |
| 386 if (table_entry->needs_frame) { | 387 if (table_entry->needs_frame) { |
| 387 DCHECK(!info()->saves_caller_doubles()); | 388 DCHECK(!info()->saves_caller_doubles()); |
| 388 __ push(Immediate(ExternalReference::ForDeoptEntry(entry))); | 389 __ push(Immediate(ExternalReference::ForDeoptEntry(entry))); |
| 389 if (needs_frame.is_bound()) { | 390 __ call(&needs_frame); |
| 390 __ jmp(&needs_frame); | |
| 391 } else { | |
| 392 __ bind(&needs_frame); | |
| 393 __ push(MemOperand(ebp, StandardFrameConstants::kContextOffset)); | |
| 394 // This variant of deopt can only be used with stubs. Since we don't | |
| 395 // have a function pointer to install in the stack frame that we're | |
| 396 // building, install a special marker there instead. | |
| 397 DCHECK(info()->IsStub()); | |
| 398 __ push(Immediate(Smi::FromInt(StackFrame::STUB))); | |
| 399 // Push a PC inside the function so that the deopt code can find where | |
| 400 // the deopt comes from. It doesn't have to be the precise return | |
| 401 // address of a "calling" LAZY deopt, it only has to be somewhere | |
| 402 // inside the code body. | |
| 403 Label push_approx_pc; | |
| 404 __ call(&push_approx_pc); | |
| 405 __ bind(&push_approx_pc); | |
| 406 // Push the continuation which was stashed were the ebp should | |
| 407 // be. Replace it with the saved ebp. | |
| 408 __ push(MemOperand(esp, 3 * kPointerSize)); | |
| 409 __ mov(MemOperand(esp, 4 * kPointerSize), ebp); | |
| 410 __ lea(ebp, MemOperand(esp, 4 * kPointerSize)); | |
| 411 __ ret(0); // Call the continuation without clobbering registers. | |
| 412 } | |
| 413 } else { | 391 } else { |
| 414 __ call(entry, RelocInfo::RUNTIME_ENTRY); | 392 __ call(entry, RelocInfo::RUNTIME_ENTRY); |
| 415 } | 393 } |
| 416 } | 394 } |
| 395 if (needs_frame.is_linked()) { |
| 396 __ bind(&needs_frame); |
| 397 |
| 398 /* stack layout |
| 399 4: entry address |
| 400 3: return address <-- esp |
| 401 2: garbage |
| 402 1: garbage |
| 403 0: garbage |
| 404 */ |
| 405 __ sub(esp, Immediate(kPointerSize)); // Reserve space for stub marker. |
| 406 __ push(MemOperand(esp, kPointerSize)); // Copy return address. |
| 407 __ push(MemOperand(esp, 3 * kPointerSize)); // Copy entry address. |
| 408 |
| 409 /* stack layout |
| 410 4: entry address |
| 411 3: return address |
| 412 2: garbage |
| 413 1: return address |
| 414 0: entry address <-- esp |
| 415 */ |
| 416 __ mov(MemOperand(esp, 4 * kPointerSize), ebp); // Save ebp. |
| 417 |
| 418 // Copy context. |
| 419 __ mov(ebp, MemOperand(ebp, StandardFrameConstants::kContextOffset)); |
| 420 __ mov(MemOperand(esp, 3 * kPointerSize), ebp); |
| 421 // Fill ebp with the right stack frame address. |
| 422 __ lea(ebp, MemOperand(esp, 4 * kPointerSize)); |
| 423 |
| 424 // This variant of deopt can only be used with stubs. Since we don't |
| 425 // have a function pointer to install in the stack frame that we're |
| 426 // building, install a special marker there instead. |
| 427 DCHECK(info()->IsStub()); |
| 428 __ mov(MemOperand(esp, 2 * kPointerSize), |
| 429 Immediate(Smi::FromInt(StackFrame::STUB))); |
| 430 |
| 431 /* stack layout |
| 432 4: old ebp |
| 433 3: context pointer |
| 434 2: stub marker |
| 435 1: return address |
| 436 0: entry address <-- esp |
| 437 */ |
| 438 __ ret(0); // Call the continuation without clobbering registers. |
| 439 } |
| 417 return !is_aborted(); | 440 return !is_aborted(); |
| 418 } | 441 } |
| 419 | 442 |
| 420 | 443 |
| 421 bool LCodeGen::GenerateDeferredCode() { | 444 bool LCodeGen::GenerateDeferredCode() { |
| 422 DCHECK(is_generating()); | 445 DCHECK(is_generating()); |
| 423 if (deferred_.length() > 0) { | 446 if (deferred_.length() > 0) { |
| 424 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 447 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
| 425 LDeferredCode* code = deferred_[i]; | 448 LDeferredCode* code = deferred_[i]; |
| 426 X87Stack copy(code->x87_stack()); | 449 X87Stack copy(code->x87_stack()); |
| (...skipping 5960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6387 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6410 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 6388 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6411 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 6389 } | 6412 } |
| 6390 | 6413 |
| 6391 | 6414 |
| 6392 #undef __ | 6415 #undef __ |
| 6393 | 6416 |
| 6394 } } // namespace v8::internal | 6417 } } // namespace v8::internal |
| 6395 | 6418 |
| 6396 #endif // V8_TARGET_ARCH_X87 | 6419 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |