Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 7618007: Simplify handling of exits from with and catch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Incorporate review comments Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/frames-x64.h ('k') | test/mjsunit/with-leave.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 2369 matching lines...) Expand 10 before | Expand all | Expand 10 after
2380 2380
2381 2381
2382 Operand MacroAssembler::SafepointRegisterSlot(Register reg) { 2382 Operand MacroAssembler::SafepointRegisterSlot(Register reg) {
2383 return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 2383 return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
2384 } 2384 }
2385 2385
2386 2386
2387 void MacroAssembler::PushTryHandler(CodeLocation try_location, 2387 void MacroAssembler::PushTryHandler(CodeLocation try_location,
2388 HandlerType type) { 2388 HandlerType type) {
2389 // Adjust this code if not the case. 2389 // Adjust this code if not the case.
2390 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); 2390 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
2391 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2392 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize);
2393 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
2394 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize);
2395 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
2391 2396
2392 // The pc (return address) is already on TOS. This code pushes state, 2397 // The pc (return address) is already on TOS. This code pushes state,
2393 // frame pointer and current handler. Check that they are expected 2398 // frame pointer, context, and current handler.
2394 // next on the stack, in that order.
2395 ASSERT_EQ(StackHandlerConstants::kStateOffset,
2396 StackHandlerConstants::kPCOffset - kPointerSize);
2397 ASSERT_EQ(StackHandlerConstants::kFPOffset,
2398 StackHandlerConstants::kStateOffset - kPointerSize);
2399 ASSERT_EQ(StackHandlerConstants::kNextOffset,
2400 StackHandlerConstants::kFPOffset - kPointerSize);
2401
2402 if (try_location == IN_JAVASCRIPT) { 2399 if (try_location == IN_JAVASCRIPT) {
2403 if (type == TRY_CATCH_HANDLER) { 2400 if (type == TRY_CATCH_HANDLER) {
2404 push(Immediate(StackHandler::TRY_CATCH)); 2401 push(Immediate(StackHandler::TRY_CATCH));
2405 } else { 2402 } else {
2406 push(Immediate(StackHandler::TRY_FINALLY)); 2403 push(Immediate(StackHandler::TRY_FINALLY));
2407 } 2404 }
2408 push(rbp); 2405 push(rbp);
2406 push(rsi);
2409 } else { 2407 } else {
2410 ASSERT(try_location == IN_JS_ENTRY); 2408 ASSERT(try_location == IN_JS_ENTRY);
2411 // The frame pointer does not point to a JS frame so we save NULL 2409 // The frame pointer does not point to a JS frame so we save NULL
2412 // for rbp. We expect the code throwing an exception to check rbp 2410 // for rbp. We expect the code throwing an exception to check rbp
2413 // before dereferencing it to restore the context. 2411 // before dereferencing it to restore the context.
2414 push(Immediate(StackHandler::ENTRY)); 2412 push(Immediate(StackHandler::ENTRY));
2415 push(Immediate(0)); // NULL frame pointer. 2413 push(Immediate(0)); // NULL frame pointer.
2414 Push(Smi::FromInt(0)); // No context.
2416 } 2415 }
2417 // Save the current handler. 2416 // Save the current handler.
2418 Operand handler_operand = 2417 Operand handler_operand =
2419 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); 2418 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate()));
2420 push(handler_operand); 2419 push(handler_operand);
2421 // Link this handler. 2420 // Link this handler.
2422 movq(handler_operand, rsp); 2421 movq(handler_operand, rsp);
2423 } 2422 }
2424 2423
2425 2424
2426 void MacroAssembler::PopTryHandler() { 2425 void MacroAssembler::PopTryHandler() {
2427 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); 2426 ASSERT_EQ(0, StackHandlerConstants::kNextOffset);
2428 // Unlink this handler. 2427 // Unlink this handler.
2429 Operand handler_operand = 2428 Operand handler_operand =
2430 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); 2429 ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate()));
2431 pop(handler_operand); 2430 pop(handler_operand);
2432 // Remove the remaining fields. 2431 // Remove the remaining fields.
2433 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 2432 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
2434 } 2433 }
2435 2434
2436 2435
2437 void MacroAssembler::Throw(Register value) { 2436 void MacroAssembler::Throw(Register value) {
2438 // Check that stack should contain next handler, frame pointer, state and 2437 // Adjust this code if not the case.
2439 // return address in that order. 2438 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
2440 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize == 2439 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2441 StackHandlerConstants::kStateOffset); 2440 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize);
2442 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize == 2441 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
2443 StackHandlerConstants::kPCOffset); 2442 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize);
2443 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
2444 // Keep thrown value in rax. 2444 // Keep thrown value in rax.
2445 if (!value.is(rax)) { 2445 if (!value.is(rax)) {
2446 movq(rax, value); 2446 movq(rax, value);
2447 } 2447 }
2448 2448
2449 ExternalReference handler_address(Isolate::k_handler_address, isolate()); 2449 ExternalReference handler_address(Isolate::k_handler_address, isolate());
2450 Operand handler_operand = ExternalOperand(handler_address); 2450 Operand handler_operand = ExternalOperand(handler_address);
2451 movq(rsp, handler_operand); 2451 movq(rsp, handler_operand);
2452 // get next in chain 2452 // get next in chain
2453 pop(handler_operand); 2453 pop(handler_operand);
2454 pop(rbp); // pop frame pointer 2454 pop(rsi); // Context.
2455 pop(rdx); // remove state 2455 pop(rbp); // Frame pointer.
2456 pop(rdx); // State.
2456 2457
2457 // Before returning we restore the context from the frame pointer if not NULL. 2458 // If the handler is a JS frame, restore the context to the frame.
2458 // The frame pointer is NULL in the exception handler of a JS entry frame. 2459 // (rdx == ENTRY) == (rbp == 0) == (rsi == 0), so we could test any
2459 Set(rsi, 0); // Tentatively set context pointer to NULL 2460 // of them.
2460 Label skip; 2461 Label skip;
2461 cmpq(rbp, Immediate(0)); 2462 cmpq(rdx, Immediate(StackHandler::ENTRY));
2462 j(equal, &skip, Label::kNear); 2463 j(equal, &skip, Label::kNear);
2463 movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2464 movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
2464 bind(&skip); 2465 bind(&skip);
2466
2465 ret(0); 2467 ret(0);
2466 } 2468 }
2467 2469
2468 2470
2469 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, 2471 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
2470 Register value) { 2472 Register value) {
2473 // Adjust this code if not the case.
2474 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
2475 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2476 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize);
2477 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
2478 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize);
2479 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
2471 // Keep thrown value in rax. 2480 // Keep thrown value in rax.
2472 if (!value.is(rax)) { 2481 if (!value.is(rax)) {
2473 movq(rax, value); 2482 movq(rax, value);
2474 } 2483 }
2475 // Fetch top stack handler. 2484 // Fetch top stack handler.
2476 ExternalReference handler_address(Isolate::k_handler_address, isolate()); 2485 ExternalReference handler_address(Isolate::k_handler_address, isolate());
2477 Load(rsp, handler_address); 2486 Load(rsp, handler_address);
2478 2487
2479 // Unwind the handlers until the ENTRY handler is found. 2488 // Unwind the handlers until the ENTRY handler is found.
2480 Label loop, done; 2489 Label loop, done;
(...skipping 19 matching lines...) Expand all
2500 Set(rax, static_cast<int64_t>(false)); 2509 Set(rax, static_cast<int64_t>(false));
2501 Store(external_caught, rax); 2510 Store(external_caught, rax);
2502 2511
2503 // Set pending exception and rax to out of memory exception. 2512 // Set pending exception and rax to out of memory exception.
2504 ExternalReference pending_exception(Isolate::k_pending_exception_address, 2513 ExternalReference pending_exception(Isolate::k_pending_exception_address,
2505 isolate()); 2514 isolate());
2506 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); 2515 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE);
2507 Store(pending_exception, rax); 2516 Store(pending_exception, rax);
2508 } 2517 }
2509 2518
2510 // Clear the context pointer. 2519 // Discard the context saved in the handler and clear the context pointer.
2520 pop(rdx);
2511 Set(rsi, 0); 2521 Set(rsi, 0);
2512 2522
2513 // Restore registers from handler. 2523 pop(rbp); // Restore frame pointer.
2514 STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize == 2524 pop(rdx); // Discard state.
2515 StackHandlerConstants::kFPOffset);
2516 pop(rbp); // FP
2517 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize ==
2518 StackHandlerConstants::kStateOffset);
2519 pop(rdx); // State
2520 2525
2521 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize ==
2522 StackHandlerConstants::kPCOffset);
2523 ret(0); 2526 ret(0);
2524 } 2527 }
2525 2528
2526 2529
2527 void MacroAssembler::Ret() { 2530 void MacroAssembler::Ret() {
2528 ret(0); 2531 ret(0);
2529 } 2532 }
2530 2533
2531 2534
2532 void MacroAssembler::Ret(int bytes_dropped, Register scratch) { 2535 void MacroAssembler::Ret(int bytes_dropped, Register scratch) {
(...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after
3849 CPU::FlushICache(address_, size_); 3852 CPU::FlushICache(address_, size_);
3850 3853
3851 // Check that the code was patched as expected. 3854 // Check that the code was patched as expected.
3852 ASSERT(masm_.pc_ == address_ + size_); 3855 ASSERT(masm_.pc_ == address_ + size_);
3853 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 3856 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
3854 } 3857 }
3855 3858
3856 } } // namespace v8::internal 3859 } } // namespace v8::internal
3857 3860
3858 #endif // V8_TARGET_ARCH_X64 3861 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/frames-x64.h ('k') | test/mjsunit/with-leave.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698