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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 960273002: Move stack unwinding logic into the runtime. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased. Created 5 years, 9 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 // Return and remove the on-stack parameters. 1036 // Return and remove the on-stack parameters.
1037 __ bind(&done); 1037 __ bind(&done);
1038 __ ret(3 * kPointerSize); 1038 __ ret(3 * kPointerSize);
1039 1039
1040 // Do the runtime call to allocate the arguments object. 1040 // Do the runtime call to allocate the arguments object.
1041 __ bind(&runtime); 1041 __ bind(&runtime);
1042 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); 1042 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1);
1043 } 1043 }
1044 1044
1045 1045
1046 static void ThrowPendingException(MacroAssembler* masm) {
1047 Isolate* isolate = masm->isolate();
1048
1049 ExternalReference pending_handler_context_address(
1050 Isolate::kPendingHandlerContextAddress, isolate);
1051 ExternalReference pending_handler_code_address(
1052 Isolate::kPendingHandlerCodeAddress, isolate);
1053 ExternalReference pending_handler_offset_address(
1054 Isolate::kPendingHandlerOffsetAddress, isolate);
1055 ExternalReference pending_handler_fp_address(
1056 Isolate::kPendingHandlerFPAddress, isolate);
1057 ExternalReference pending_handler_sp_address(
1058 Isolate::kPendingHandlerSPAddress, isolate);
1059
1060 // Ask the runtime for help to determine the handler. This will set rax to
1061 // contain the current pending exception, don't clobber it.
1062 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate);
1063 #ifdef _WIN64
1064 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9.
1065 __ movp(rcx, Immediate(0)); // argc.
1066 __ movp(rdx, Immediate(0)); // argv.
1067 __ Move(r8, ExternalReference::isolate_address(isolate));
1068 #else // _WIN64
1069 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
1070 __ movp(rdi, Immediate(0)); // argc.
1071 __ movp(rsi, Immediate(0)); // argv.
1072 __ Move(rdx, ExternalReference::isolate_address(isolate));
1073 #endif // _WIN64
1074 __ Move(rbx, find_handler);
1075 __ call(rbx);
1076
1077 // Retrieve the handler context, SP and FP.
1078 __ movp(rsi, masm->ExternalOperand(pending_handler_context_address));
1079 __ movp(rsp, masm->ExternalOperand(pending_handler_sp_address));
1080 __ movp(rbp, masm->ExternalOperand(pending_handler_fp_address));
1081
1082 // If the handler is a JS frame, restore the context to the frame.
1083 // (kind == ENTRY) == (rbp == 0) == (rsi == 0), so we could test either
1084 // rbp or rsi.
1085 Label skip;
1086 __ testp(rsi, rsi);
1087 __ j(zero, &skip, Label::kNear);
1088 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
1089 __ bind(&skip);
1090
1091 // Compute the handler entry address and jump to it.
1092 __ movp(rdi, masm->ExternalOperand(pending_handler_code_address));
1093 __ movp(rdx, masm->ExternalOperand(pending_handler_offset_address));
1094 __ leap(rdi, FieldOperand(rdi, rdx, times_1, Code::kHeaderSize));
1095 __ jmp(rdi);
1096 }
1097
1098
1046 void RegExpExecStub::Generate(MacroAssembler* masm) { 1099 void RegExpExecStub::Generate(MacroAssembler* masm) {
1047 // Just jump directly to runtime if native RegExp is not selected at compile 1100 // Just jump directly to runtime if native RegExp is not selected at compile
1048 // time or if regexp entry in generated code is turned off runtime switch or 1101 // time or if regexp entry in generated code is turned off runtime switch or
1049 // at compilation. 1102 // at compilation.
1050 #ifdef V8_INTERPRETED_REGEXP 1103 #ifdef V8_INTERPRETED_REGEXP
1051 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); 1104 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1);
1052 #else // V8_INTERPRETED_REGEXP 1105 #else // V8_INTERPRETED_REGEXP
1053 1106
1054 // Stack frame on entry. 1107 // Stack frame on entry.
1055 // rsp[0] : return address 1108 // rsp[0] : return address
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 // haven't created the exception yet. Handle that in the runtime system. 1475 // haven't created the exception yet. Handle that in the runtime system.
1423 // TODO(592): Rerunning the RegExp to get the stack overflow exception. 1476 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
1424 ExternalReference pending_exception_address( 1477 ExternalReference pending_exception_address(
1425 Isolate::kPendingExceptionAddress, isolate()); 1478 Isolate::kPendingExceptionAddress, isolate());
1426 Operand pending_exception_operand = 1479 Operand pending_exception_operand =
1427 masm->ExternalOperand(pending_exception_address, rbx); 1480 masm->ExternalOperand(pending_exception_address, rbx);
1428 __ movp(rax, pending_exception_operand); 1481 __ movp(rax, pending_exception_operand);
1429 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex); 1482 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
1430 __ cmpp(rax, rdx); 1483 __ cmpp(rax, rdx);
1431 __ j(equal, &runtime); 1484 __ j(equal, &runtime);
1432 __ movp(pending_exception_operand, rdx);
1433 1485
1434 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex); 1486 // For exception, throw the exception again.
1435 Label termination_exception; 1487 __ EnterExitFrame(false);
1436 __ j(equal, &termination_exception, Label::kNear); 1488 ThrowPendingException(masm);
1437 __ Throw(rax);
1438
1439 __ bind(&termination_exception);
1440 __ ThrowUncatchable(rax);
1441 1489
1442 // Do the runtime call to execute the regexp. 1490 // Do the runtime call to execute the regexp.
1443 __ bind(&runtime); 1491 __ bind(&runtime);
1444 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); 1492 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1);
1445 1493
1446 // Deferred code for string handling. 1494 // Deferred code for string handling.
1447 // (7) Not a long external string? If yes, go to (10). 1495 // (7) Not a long external string? If yes, go to (10).
1448 __ bind(&not_seq_nor_cons); 1496 __ bind(&not_seq_nor_cons);
1449 // Compare flags are still set from (3). 1497 // Compare flags are still set from (3).
1450 __ j(greater, &not_long_external, Label::kNear); // Go to (10). 1498 __ j(greater, &not_long_external, Label::kNear); // Go to (10).
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
2419 __ j(not_equal, &okay, Label::kNear); 2467 __ j(not_equal, &okay, Label::kNear);
2420 __ int3(); 2468 __ int3();
2421 __ bind(&okay); 2469 __ bind(&okay);
2422 } 2470 }
2423 2471
2424 // Check result for exception sentinel. 2472 // Check result for exception sentinel.
2425 Label exception_returned; 2473 Label exception_returned;
2426 __ CompareRoot(rax, Heap::kExceptionRootIndex); 2474 __ CompareRoot(rax, Heap::kExceptionRootIndex);
2427 __ j(equal, &exception_returned); 2475 __ j(equal, &exception_returned);
2428 2476
2429 ExternalReference pending_exception_address(
2430 Isolate::kPendingExceptionAddress, isolate());
2431
2432 // Check that there is no pending exception, otherwise we 2477 // Check that there is no pending exception, otherwise we
2433 // should have returned the exception sentinel. 2478 // should have returned the exception sentinel.
2434 if (FLAG_debug_code) { 2479 if (FLAG_debug_code) {
2435 Label okay; 2480 Label okay;
2436 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); 2481 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex);
2482 ExternalReference pending_exception_address(
2483 Isolate::kPendingExceptionAddress, isolate());
2437 Operand pending_exception_operand = 2484 Operand pending_exception_operand =
2438 masm->ExternalOperand(pending_exception_address); 2485 masm->ExternalOperand(pending_exception_address);
2439 __ cmpp(r14, pending_exception_operand); 2486 __ cmpp(r14, pending_exception_operand);
2440 __ j(equal, &okay, Label::kNear); 2487 __ j(equal, &okay, Label::kNear);
2441 __ int3(); 2488 __ int3();
2442 __ bind(&okay); 2489 __ bind(&okay);
2443 } 2490 }
2444 2491
2445 // Exit the JavaScript to C++ exit frame. 2492 // Exit the JavaScript to C++ exit frame.
2446 __ LeaveExitFrame(save_doubles()); 2493 __ LeaveExitFrame(save_doubles());
2447 __ ret(0); 2494 __ ret(0);
2448 2495
2449 // Handling of exception. 2496 // Handling of exception.
2450 __ bind(&exception_returned); 2497 __ bind(&exception_returned);
2451 2498 ThrowPendingException(masm);
2452 // Retrieve the pending exception.
2453 Operand pending_exception_operand =
2454 masm->ExternalOperand(pending_exception_address);
2455 __ movp(rax, pending_exception_operand);
2456
2457 // Clear the pending exception.
2458 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
2459 __ movp(pending_exception_operand, rdx);
2460
2461 // Special handling of termination exceptions which are uncatchable
2462 // by javascript code.
2463 Label throw_termination_exception;
2464 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
2465 __ j(equal, &throw_termination_exception);
2466
2467 // Handle normal exception.
2468 __ Throw(rax);
2469
2470 __ bind(&throw_termination_exception);
2471 __ ThrowUncatchable(rax);
2472 } 2499 }
2473 2500
2474 2501
2475 void JSEntryStub::Generate(MacroAssembler* masm) { 2502 void JSEntryStub::Generate(MacroAssembler* masm) {
2476 Label invoke, handler_entry, exit; 2503 Label invoke, handler_entry, exit;
2477 Label not_outermost_js, not_outermost_js_2; 2504 Label not_outermost_js, not_outermost_js_2;
2478 2505
2479 ProfileEntryHookStub::MaybeCallEntryHook(masm); 2506 ProfileEntryHookStub::MaybeCallEntryHook(masm);
2480 2507
2481 { // NOLINT. Scope block confuses linter. 2508 { // NOLINT. Scope block confuses linter.
(...skipping 2613 matching lines...) Expand 10 before | Expand all | Expand 10 after
5095 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, 5122 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg,
5096 kStackSpace, nullptr, return_value_operand, NULL); 5123 kStackSpace, nullptr, return_value_operand, NULL);
5097 } 5124 }
5098 5125
5099 5126
5100 #undef __ 5127 #undef __
5101 5128
5102 } } // namespace v8::internal 5129 } } // namespace v8::internal
5103 5130
5104 #endif // V8_TARGET_ARCH_X64 5131 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698