| OLD | NEW | 
|     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  Loading... | 
|   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  Loading... | 
|  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 | 
| OLD | NEW |