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

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

Issue 3792003: Optimizing HandleScope. Also fixed HandleScope destruction when API getter th... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 2 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/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 462
463 463
464 static int Offset(ExternalReference ref0, ExternalReference ref1) { 464 static int Offset(ExternalReference ref0, ExternalReference ref1) {
465 int64_t offset = (ref0.address() - ref1.address()); 465 int64_t offset = (ref0.address() - ref1.address());
466 // Check that fits into int. 466 // Check that fits into int.
467 ASSERT(static_cast<int>(offset) == offset); 467 ASSERT(static_cast<int>(offset) == offset);
468 return static_cast<int>(offset); 468 return static_cast<int>(offset);
469 } 469 }
470 470
471 471
472 void MacroAssembler::PushHandleScope(Register scratch) { 472 void MacroAssembler::PrepareCallApiFunction(int stack_space) {
473 ExternalReference extensions_address = 473 EnterApiExitFrame(stack_space, 0);
474 ExternalReference::handle_scope_extensions_address();
475 const int kExtensionsOffset = 0;
476 const int kNextOffset = Offset(
477 ExternalReference::handle_scope_next_address(),
478 extensions_address);
479 const int kLimitOffset = Offset(
480 ExternalReference::handle_scope_limit_address(),
481 extensions_address);
482
483 // Push the number of extensions, smi-tagged so the gc will ignore it.
484 movq(kScratchRegister, extensions_address);
485 movq(scratch, Operand(kScratchRegister, kExtensionsOffset));
486 movq(Operand(kScratchRegister, kExtensionsOffset), Immediate(0));
487 Integer32ToSmi(scratch, scratch);
488 push(scratch);
489 // Push next and limit pointers which will be wordsize aligned and
490 // hence automatically smi tagged.
491 push(Operand(kScratchRegister, kNextOffset));
492 push(Operand(kScratchRegister, kLimitOffset));
493 } 474 }
494 475
495 476
496 Object* MacroAssembler::PopHandleScopeHelper(Register saved, 477 void MacroAssembler::CallApiFunctionAndReturn(ApiFunction* function) {
497 Register scratch, 478 Label empty_result;
498 bool gc_allowed) { 479 Label prologue;
499 ExternalReference extensions_address = 480 Label promote_scheduled_exception;
500 ExternalReference::handle_scope_extensions_address(); 481 Label delete_allocated_handles;
501 const int kExtensionsOffset = 0; 482 Label leave_exit_frame;
502 const int kNextOffset = Offset( 483 Label write_back;
503 ExternalReference::handle_scope_next_address(), 484
504 extensions_address); 485 ExternalReference next_address =
486 ExternalReference::handle_scope_next_address();
487 const int kNextOffset = 0;
505 const int kLimitOffset = Offset( 488 const int kLimitOffset = Offset(
506 ExternalReference::handle_scope_limit_address(), 489 ExternalReference::handle_scope_limit_address(),
507 extensions_address); 490 next_address);
491 const int kLevelOffset = Offset(
492 ExternalReference::handle_scope_level_address(),
493 next_address);
494 ExternalReference scheduled_exception_address =
495 ExternalReference::scheduled_exception_address();
508 496
509 Object* result = NULL; 497 // Allocate HandleScope in callee-save registers.
510 Label write_back; 498 Register prev_next_address_reg = r14;
511 movq(kScratchRegister, extensions_address); 499 Register prev_limit_reg = rbx;
512 cmpq(Operand(kScratchRegister, kExtensionsOffset), Immediate(0)); 500 Register base_reg = kSmiConstantRegister;
513 j(equal, &write_back); 501 movq(base_reg, next_address);
514 push(saved); 502 movq(prev_next_address_reg, Operand(base_reg, kNextOffset));
515 if (gc_allowed) { 503 movq(prev_limit_reg, Operand(base_reg, kLimitOffset));
516 CallRuntime(Runtime::kDeleteHandleScopeExtensions, 0); 504 addl(Operand(base_reg, kLevelOffset), Immediate(1));
517 } else { 505 // Call the api function!
518 result = TryCallRuntime(Runtime::kDeleteHandleScopeExtensions, 0); 506 movq(rax,
519 if (result->IsFailure()) return result; 507 reinterpret_cast<int64_t>(function->address()),
520 } 508 RelocInfo::RUNTIME_ENTRY);
521 pop(saved); 509 call(rax);
522 movq(kScratchRegister, extensions_address);
523 510
524 bind(&write_back); 511 #ifdef _WIN64
525 pop(Operand(kScratchRegister, kLimitOffset)); 512 // rax keeps a pointer to v8::Handle, unpack it.
526 pop(Operand(kScratchRegister, kNextOffset)); 513 movq(rax, Operand(rax, 0));
527 pop(scratch); 514 #endif
528 SmiToInteger32(scratch, scratch); 515 // Check if the result handle holds 0.
529 movq(Operand(kScratchRegister, kExtensionsOffset), scratch); 516 testq(rax, rax);
517 j(zero, &empty_result);
518 // It was non-zero. Dereference to get the result value.
519 movq(rax, Operand(rax, 0));
520 bind(&prologue);
530 521
531 return result; 522 // No more valid handles (the result handle was the last one). Restore
523 // previous handle scope.
524 subl(Operand(base_reg, kLevelOffset), Immediate(1));
525 movq(Operand(base_reg, kNextOffset), prev_next_address_reg);
526 cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset));
527 j(not_equal, &delete_allocated_handles);
528 bind(&leave_exit_frame);
529 InitializeSmiConstantRegister();
530
531 // Check if the function scheduled an exception.
532 movq(rsi, scheduled_exception_address);
533 Cmp(Operand(rsi, 0), Factory::the_hole_value());
534 j(not_equal, &promote_scheduled_exception);
535
536 LeaveExitFrame();
537 ret(0);
538
539 bind(&promote_scheduled_exception);
540 TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
541
542 bind(&empty_result);
543 // It was zero; the result is undefined.
544 Move(rax, Factory::undefined_value());
545 jmp(&prologue);
546
547 // HandleScope limit has changed. Delete allocated extensions.
548 bind(&delete_allocated_handles);
549 movq(Operand(base_reg, kLimitOffset), prev_limit_reg);
550 movq(prev_limit_reg, rax);
551 movq(rax, ExternalReference::delete_handle_scope_extensions());
552 call(rax);
553 movq(rax, prev_limit_reg);
554 jmp(&leave_exit_frame);
532 } 555 }
533 556
534 557
535 void MacroAssembler::PopHandleScope(Register saved, Register scratch) {
536 PopHandleScopeHelper(saved, scratch, true);
537 }
538
539
540 Object* MacroAssembler::TryPopHandleScope(Register saved, Register scratch) {
541 return PopHandleScopeHelper(saved, scratch, false);
542 }
543
544
545 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext, 558 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext,
546 int result_size) { 559 int result_size) {
547 // Set the entry point and jump to the C entry runtime stub. 560 // Set the entry point and jump to the C entry runtime stub.
548 movq(rbx, ext); 561 movq(rbx, ext);
549 CEntryStub ces(result_size); 562 CEntryStub ces(result_size);
550 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 563 jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
551 } 564 }
552 565
553 566
554 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { 567 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
(...skipping 1668 matching lines...) Expand 10 before | Expand all | Expand 10 after
2223 CPU::FlushICache(address_, size_); 2236 CPU::FlushICache(address_, size_);
2224 2237
2225 // Check that the code was patched as expected. 2238 // Check that the code was patched as expected.
2226 ASSERT(masm_.pc_ == address_ + size_); 2239 ASSERT(masm_.pc_ == address_ + size_);
2227 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2240 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2228 } 2241 }
2229 2242
2230 } } // namespace v8::internal 2243 } } // namespace v8::internal
2231 2244
2232 #endif // V8_TARGET_ARCH_X64 2245 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698