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 |