| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 __ movq(Operand(kScratchRegister, 0), rcx); | 252 __ movq(Operand(kScratchRegister, 0), rcx); |
| 253 __ movq(rsp, rdx); | 253 __ movq(rsp, rdx); |
| 254 __ pop(rbp); // pop frame pointer | 254 __ pop(rbp); // pop frame pointer |
| 255 __ pop(rdx); // remove code pointer | 255 __ pop(rdx); // remove code pointer |
| 256 __ pop(rdx); // remove state | 256 __ pop(rdx); // remove state |
| 257 | 257 |
| 258 // Before returning we restore the context from the frame pointer if not NULL. | 258 // Before returning we restore the context from the frame pointer if not NULL. |
| 259 // The frame pointer is NULL in the exception handler of a JS entry frame. | 259 // The frame pointer is NULL in the exception handler of a JS entry frame. |
| 260 __ xor_(rsi, rsi); // tentatively set context pointer to NULL | 260 __ xor_(rsi, rsi); // tentatively set context pointer to NULL |
| 261 Label skip; | 261 Label skip; |
| 262 __ cmp(rbp, Immediate(0)); | 262 __ cmpq(rbp, Immediate(0)); |
| 263 __ j(equal, &skip); | 263 __ j(equal, &skip); |
| 264 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 264 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 265 __ bind(&skip); | 265 __ bind(&skip); |
| 266 | 266 |
| 267 __ ret(0); | 267 __ ret(0); |
| 268 } | 268 } |
| 269 | 269 |
| 270 | 270 |
| 271 | 271 |
| 272 void CEntryStub::GenerateCore(MacroAssembler* masm, | 272 void CEntryStub::GenerateCore(MacroAssembler* masm, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 287 __ movq(kScratchRegister, | 287 __ movq(kScratchRegister, |
| 288 FUNCTION_ADDR(Runtime::PerformGC), | 288 FUNCTION_ADDR(Runtime::PerformGC), |
| 289 RelocInfo::RUNTIME_ENTRY); | 289 RelocInfo::RUNTIME_ENTRY); |
| 290 __ call(kScratchRegister); | 290 __ call(kScratchRegister); |
| 291 } | 291 } |
| 292 | 292 |
| 293 ExternalReference scope_depth = | 293 ExternalReference scope_depth = |
| 294 ExternalReference::heap_always_allocate_scope_depth(); | 294 ExternalReference::heap_always_allocate_scope_depth(); |
| 295 if (always_allocate_scope) { | 295 if (always_allocate_scope) { |
| 296 __ movq(kScratchRegister, scope_depth); | 296 __ movq(kScratchRegister, scope_depth); |
| 297 __ inc(Operand(kScratchRegister, 0)); | 297 __ incl(Operand(kScratchRegister, 0)); |
| 298 } | 298 } |
| 299 | 299 |
| 300 // Call C function. | 300 // Call C function. |
| 301 #ifdef __MSVC__ | 301 #ifdef __MSVC__ |
| 302 // MSVC passes arguments in rcx, rdx, r8, r9 | 302 // MSVC passes arguments in rcx, rdx, r8, r9 |
| 303 __ movq(rcx, rdi); // argc. | 303 __ movq(rcx, rdi); // argc. |
| 304 __ movq(rdx, rsi); // argv. | 304 __ movq(rdx, rsi); // argv. |
| 305 #else // ! defined(__MSVC__) | 305 #else // ! defined(__MSVC__) |
| 306 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. | 306 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. |
| 307 // First two arguments are already in rdi, rsi. | 307 // First two arguments are already in rdi, rsi. |
| 308 #endif | 308 #endif |
| 309 __ call(rbx); | 309 __ call(rbx); |
| 310 // Result is in rax - do not destroy this register! | 310 // Result is in rax - do not destroy this register! |
| 311 | 311 |
| 312 if (always_allocate_scope) { | 312 if (always_allocate_scope) { |
| 313 __ movq(kScratchRegister, scope_depth); | 313 __ movq(kScratchRegister, scope_depth); |
| 314 __ dec(Operand(kScratchRegister, 0)); | 314 __ decl(Operand(kScratchRegister, 0)); |
| 315 } | 315 } |
| 316 | 316 |
| 317 // Check for failure result. | 317 // Check for failure result. |
| 318 Label failure_returned; | 318 Label failure_returned; |
| 319 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); | 319 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); |
| 320 __ lea(rcx, Operand(rax, 1)); | 320 __ lea(rcx, Operand(rax, 1)); |
| 321 // Lower 2 bits of rcx are 0 iff rax has failure tag. | 321 // Lower 2 bits of rcx are 0 iff rax has failure tag. |
| 322 __ testl(rcx, Immediate(kFailureTagMask)); | 322 __ testl(rcx, Immediate(kFailureTagMask)); |
| 323 __ j(zero, &failure_returned); | 323 __ j(zero, &failure_returned); |
| 324 | 324 |
| 325 // Exit the JavaScript to C++ exit frame. | 325 // Exit the JavaScript to C++ exit frame. |
| 326 __ LeaveExitFrame(frame_type); | 326 __ LeaveExitFrame(frame_type); |
| 327 __ ret(0); | 327 __ ret(0); |
| 328 | 328 |
| 329 // Handling of failure. | 329 // Handling of failure. |
| 330 __ bind(&failure_returned); | 330 __ bind(&failure_returned); |
| 331 | 331 |
| 332 Label retry; | 332 Label retry; |
| 333 // If the returned exception is RETRY_AFTER_GC continue at retry label | 333 // If the returned exception is RETRY_AFTER_GC continue at retry label |
| 334 ASSERT(Failure::RETRY_AFTER_GC == 0); | 334 ASSERT(Failure::RETRY_AFTER_GC == 0); |
| 335 __ testq(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 335 __ testq(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
| 336 __ j(zero, &retry); | 336 __ j(zero, &retry); |
| 337 | 337 |
| 338 Label continue_exception; | 338 Label continue_exception; |
| 339 // If the returned failure is EXCEPTION then promote Top::pending_exception(). | 339 // If the returned failure is EXCEPTION then promote Top::pending_exception(). |
| 340 __ movq(kScratchRegister, Failure::Exception(), RelocInfo::NONE); | 340 __ movq(kScratchRegister, Failure::Exception(), RelocInfo::NONE); |
| 341 __ cmp(rax, kScratchRegister); | 341 __ cmpq(rax, kScratchRegister); |
| 342 __ j(not_equal, &continue_exception); | 342 __ j(not_equal, &continue_exception); |
| 343 | 343 |
| 344 // Retrieve the pending exception and clear the variable. | 344 // Retrieve the pending exception and clear the variable. |
| 345 ExternalReference pending_exception_address(Top::k_pending_exception_address); | 345 ExternalReference pending_exception_address(Top::k_pending_exception_address); |
| 346 __ movq(kScratchRegister, pending_exception_address); | 346 __ movq(kScratchRegister, pending_exception_address); |
| 347 __ movq(rax, Operand(kScratchRegister, 0)); | 347 __ movq(rax, Operand(kScratchRegister, 0)); |
| 348 __ movq(rdx, ExternalReference::the_hole_value_location()); | 348 __ movq(rdx, ExternalReference::the_hole_value_location()); |
| 349 __ movq(rdx, Operand(rdx, 0)); | 349 __ movq(rdx, Operand(rdx, 0)); |
| 350 __ movq(Operand(kScratchRegister, 0), rdx); | 350 __ movq(Operand(kScratchRegister, 0), rdx); |
| 351 | 351 |
| 352 __ bind(&continue_exception); | 352 __ bind(&continue_exception); |
| 353 // Special handling of out of memory exception. | 353 // Special handling of out of memory exception. |
| 354 __ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE); | 354 __ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE); |
| 355 __ cmp(rax, kScratchRegister); | 355 __ cmpq(rax, kScratchRegister); |
| 356 __ j(equal, throw_out_of_memory_exception); | 356 __ j(equal, throw_out_of_memory_exception); |
| 357 | 357 |
| 358 // Handle normal exception. | 358 // Handle normal exception. |
| 359 __ jmp(throw_normal_exception); | 359 __ jmp(throw_normal_exception); |
| 360 | 360 |
| 361 // Retry. | 361 // Retry. |
| 362 __ bind(&retry); | 362 __ bind(&retry); |
| 363 } | 363 } |
| 364 | 364 |
| 365 | 365 |
| 366 void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) { | 366 void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) { |
| 367 // Fetch top stack handler. | 367 // Fetch top stack handler. |
| 368 ExternalReference handler_address(Top::k_handler_address); | 368 ExternalReference handler_address(Top::k_handler_address); |
| 369 __ movq(kScratchRegister, handler_address); | 369 __ movq(kScratchRegister, handler_address); |
| 370 __ movq(rdx, Operand(kScratchRegister, 0)); | 370 __ movq(rdx, Operand(kScratchRegister, 0)); |
| 371 | 371 |
| 372 // Unwind the handlers until the ENTRY handler is found. | 372 // Unwind the handlers until the ENTRY handler is found. |
| 373 Label loop, done; | 373 Label loop, done; |
| 374 __ bind(&loop); | 374 __ bind(&loop); |
| 375 // Load the type of the current stack handler. | 375 // Load the type of the current stack handler. |
| 376 __ cmp(Operand(rdx, StackHandlerConstants::kStateOffset), | 376 __ cmpq(Operand(rdx, StackHandlerConstants::kStateOffset), |
| 377 Immediate(StackHandler::ENTRY)); | 377 Immediate(StackHandler::ENTRY)); |
| 378 __ j(equal, &done); | 378 __ j(equal, &done); |
| 379 // Fetch the next handler in the list. | 379 // Fetch the next handler in the list. |
| 380 __ movq(rdx, Operand(rdx, StackHandlerConstants::kNextOffset)); | 380 __ movq(rdx, Operand(rdx, StackHandlerConstants::kNextOffset)); |
| 381 __ jmp(&loop); | 381 __ jmp(&loop); |
| 382 __ bind(&done); | 382 __ bind(&done); |
| 383 | 383 |
| 384 // Set the top handler address to next handler past the current ENTRY handler. | 384 // Set the top handler address to next handler past the current ENTRY handler. |
| 385 __ movq(rax, Operand(rdx, StackHandlerConstants::kNextOffset)); | 385 __ movq(rax, Operand(rdx, StackHandlerConstants::kNextOffset)); |
| 386 __ store_rax(handler_address); | 386 __ store_rax(handler_address); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 } else { | 542 } else { |
| 543 ExternalReference entry(Builtins::JSEntryTrampoline); | 543 ExternalReference entry(Builtins::JSEntryTrampoline); |
| 544 __ load_rax(entry); | 544 __ load_rax(entry); |
| 545 } | 545 } |
| 546 __ call(FieldOperand(rax, Code::kHeaderSize)); | 546 __ call(FieldOperand(rax, Code::kHeaderSize)); |
| 547 | 547 |
| 548 // Unlink this frame from the handler chain. | 548 // Unlink this frame from the handler chain. |
| 549 __ movq(kScratchRegister, ExternalReference(Top::k_handler_address)); | 549 __ movq(kScratchRegister, ExternalReference(Top::k_handler_address)); |
| 550 __ pop(Operand(kScratchRegister, 0)); | 550 __ pop(Operand(kScratchRegister, 0)); |
| 551 // Pop next_sp. | 551 // Pop next_sp. |
| 552 __ add(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); | 552 __ addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); |
| 553 | 553 |
| 554 // Restore the top frame descriptor from the stack. | 554 // Restore the top frame descriptor from the stack. |
| 555 __ bind(&exit); | 555 __ bind(&exit); |
| 556 __ movq(kScratchRegister, ExternalReference(Top::k_c_entry_fp_address)); | 556 __ movq(kScratchRegister, ExternalReference(Top::k_c_entry_fp_address)); |
| 557 __ pop(Operand(kScratchRegister, 0)); | 557 __ pop(Operand(kScratchRegister, 0)); |
| 558 | 558 |
| 559 // Restore callee-saved registers (X64 conventions). | 559 // Restore callee-saved registers (X64 conventions). |
| 560 __ pop(rbx); | 560 __ pop(rbx); |
| 561 __ pop(rsi); | 561 __ pop(rsi); |
| 562 __ pop(rdi); | 562 __ pop(rdi); |
| 563 __ pop(r15); | 563 __ pop(r15); |
| 564 __ pop(r14); | 564 __ pop(r14); |
| 565 __ pop(r13); | 565 __ pop(r13); |
| 566 __ pop(r12); | 566 __ pop(r12); |
| 567 __ add(rsp, Immediate(2 * kPointerSize)); // remove markers | 567 __ addq(rsp, Immediate(2 * kPointerSize)); // remove markers |
| 568 | 568 |
| 569 // Restore frame pointer and return. | 569 // Restore frame pointer and return. |
| 570 __ pop(rbp); | 570 __ pop(rbp); |
| 571 __ ret(0); | 571 __ ret(0); |
| 572 } | 572 } |
| 573 | 573 |
| 574 | 574 |
| 575 #undef __ | 575 #undef __ |
| 576 | 576 |
| 577 } } // namespace v8::internal | 577 } } // namespace v8::internal |
| OLD | NEW |