| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 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 #if V8_TARGET_ARCH_X87 |     5 #if V8_TARGET_ARCH_X87 | 
|     6  |     6  | 
|     7 #include "src/base/bits.h" |     7 #include "src/base/bits.h" | 
|     8 #include "src/bootstrapper.h" |     8 #include "src/bootstrapper.h" | 
|     9 #include "src/code-stubs.h" |     9 #include "src/code-stubs.h" | 
|    10 #include "src/codegen.h" |    10 #include "src/codegen.h" | 
| (...skipping 5328 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5339   __ mov(Operand::StaticVariable(limit_address), edi); |  5339   __ mov(Operand::StaticVariable(limit_address), edi); | 
|  5340   __ mov(edi, eax); |  5340   __ mov(edi, eax); | 
|  5341   __ mov(Operand(esp, 0), |  5341   __ mov(Operand(esp, 0), | 
|  5342          Immediate(ExternalReference::isolate_address(isolate))); |  5342          Immediate(ExternalReference::isolate_address(isolate))); | 
|  5343   __ mov(eax, Immediate(delete_extensions)); |  5343   __ mov(eax, Immediate(delete_extensions)); | 
|  5344   __ call(eax); |  5344   __ call(eax); | 
|  5345   __ mov(eax, edi); |  5345   __ mov(eax, edi); | 
|  5346   __ jmp(&leave_exit_frame); |  5346   __ jmp(&leave_exit_frame); | 
|  5347 } |  5347 } | 
|  5348  |  5348  | 
|  5349 static void CallApiFunctionStubHelper(MacroAssembler* masm, |  5349 void CallApiCallbackStub::Generate(MacroAssembler* masm) { | 
|  5350                                       const ParameterCount& argc, |  | 
|  5351                                       bool return_first_arg, |  | 
|  5352                                       bool call_data_undefined, bool is_lazy) { |  | 
|  5353   // ----------- S t a t e ------------- |  5350   // ----------- S t a t e ------------- | 
|  5354   //  -- edi                 : callee |  5351   //  -- edi                 : callee | 
|  5355   //  -- ebx                 : call_data |  5352   //  -- ebx                 : call_data | 
|  5356   //  -- ecx                 : holder |  5353   //  -- ecx                 : holder | 
|  5357   //  -- edx                 : api_function_address |  5354   //  -- edx                 : api_function_address | 
|  5358   //  -- esi                 : context |  5355   //  -- esi                 : context | 
|  5359   //  -- eax                 : number of arguments if argc is a register |  | 
|  5360   //  -- |  5356   //  -- | 
|  5361   //  -- esp[0]              : return address |  5357   //  -- esp[0]              : return address | 
|  5362   //  -- esp[4]              : last argument |  5358   //  -- esp[4]              : last argument | 
|  5363   //  -- ... |  5359   //  -- ... | 
|  5364   //  -- esp[argc * 4]       : first argument |  5360   //  -- esp[argc * 4]       : first argument | 
|  5365   //  -- esp[(argc + 1) * 4] : receiver |  5361   //  -- esp[(argc + 1) * 4] : receiver | 
|  5366   // ----------------------------------- |  5362   // ----------------------------------- | 
|  5367  |  5363  | 
|  5368   Register callee = edi; |  5364   Register callee = edi; | 
|  5369   Register call_data = ebx; |  5365   Register call_data = ebx; | 
|  5370   Register holder = ecx; |  5366   Register holder = ecx; | 
|  5371   Register api_function_address = edx; |  5367   Register api_function_address = edx; | 
|  5372   Register context = esi; |  5368   Register context = esi; | 
|  5373   Register return_address = eax; |  5369   Register return_address = eax; | 
|  5374  |  5370  | 
|  5375   typedef FunctionCallbackArguments FCA; |  5371   typedef FunctionCallbackArguments FCA; | 
|  5376  |  5372  | 
|  5377   STATIC_ASSERT(FCA::kContextSaveIndex == 6); |  5373   STATIC_ASSERT(FCA::kContextSaveIndex == 6); | 
|  5378   STATIC_ASSERT(FCA::kCalleeIndex == 5); |  5374   STATIC_ASSERT(FCA::kCalleeIndex == 5); | 
|  5379   STATIC_ASSERT(FCA::kDataIndex == 4); |  5375   STATIC_ASSERT(FCA::kDataIndex == 4); | 
|  5380   STATIC_ASSERT(FCA::kReturnValueOffset == 3); |  5376   STATIC_ASSERT(FCA::kReturnValueOffset == 3); | 
|  5381   STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |  5377   STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); | 
|  5382   STATIC_ASSERT(FCA::kIsolateIndex == 1); |  5378   STATIC_ASSERT(FCA::kIsolateIndex == 1); | 
|  5383   STATIC_ASSERT(FCA::kHolderIndex == 0); |  5379   STATIC_ASSERT(FCA::kHolderIndex == 0); | 
|  5384   STATIC_ASSERT(FCA::kArgsLength == 7); |  5380   STATIC_ASSERT(FCA::kArgsLength == 7); | 
|  5385  |  5381  | 
|  5386   DCHECK(argc.is_immediate() || eax.is(argc.reg())); |  5382   DCHECK(argc.is_immediate() || eax.is(argc.reg())); | 
|  5387  |  5383  | 
|  5388   if (argc.is_immediate()) { |  5384   __ pop(return_address); | 
|  5389     __ pop(return_address); |  5385   // context save. | 
|  5390     // context save. |  5386   __ push(context); | 
|  5391     __ push(context); |  | 
|  5392   } else { |  | 
|  5393     // pop return address and save context |  | 
|  5394     __ xchg(context, Operand(esp, 0)); |  | 
|  5395     return_address = context; |  | 
|  5396   } |  | 
|  5397  |  5387  | 
|  5398   // callee |  5388   // callee | 
|  5399   __ push(callee); |  5389   __ push(callee); | 
|  5400  |  5390  | 
|  5401   // call data |  5391   // call data | 
|  5402   __ push(call_data); |  5392   __ push(call_data); | 
|  5403  |  5393  | 
|  5404   Register scratch = call_data; |  5394   Register scratch = call_data; | 
|  5405   if (!call_data_undefined) { |  5395   if (!call_data_undefined()) { | 
|  5406     // return value |  5396     // return value | 
|  5407     __ push(Immediate(masm->isolate()->factory()->undefined_value())); |  5397     __ push(Immediate(masm->isolate()->factory()->undefined_value())); | 
|  5408     // return value default |  5398     // return value default | 
|  5409     __ push(Immediate(masm->isolate()->factory()->undefined_value())); |  5399     __ push(Immediate(masm->isolate()->factory()->undefined_value())); | 
|  5410   } else { |  5400   } else { | 
|  5411     // return value |  5401     // return value | 
|  5412     __ push(scratch); |  5402     __ push(scratch); | 
|  5413     // return value default |  5403     // return value default | 
|  5414     __ push(scratch); |  5404     __ push(scratch); | 
|  5415   } |  5405   } | 
|  5416   // isolate |  5406   // isolate | 
|  5417   __ push(Immediate(reinterpret_cast<int>(masm->isolate()))); |  5407   __ push(Immediate(reinterpret_cast<int>(masm->isolate()))); | 
|  5418   // holder |  5408   // holder | 
|  5419   __ push(holder); |  5409   __ push(holder); | 
|  5420  |  5410  | 
|  5421   __ mov(scratch, esp); |  5411   __ mov(scratch, esp); | 
|  5422  |  5412  | 
|  5423   // push return address |  5413   // push return address | 
|  5424   __ push(return_address); |  5414   __ push(return_address); | 
|  5425  |  5415  | 
|  5426   if (!is_lazy) { |  5416   if (!is_lazy()) { | 
|  5427     // load context from callee |  5417     // load context from callee | 
|  5428     __ mov(context, FieldOperand(callee, JSFunction::kContextOffset)); |  5418     __ mov(context, FieldOperand(callee, JSFunction::kContextOffset)); | 
|  5429   } |  5419   } | 
|  5430  |  5420  | 
|  5431   // API function gets reference to the v8::Arguments. If CPU profiler |  5421   // API function gets reference to the v8::Arguments. If CPU profiler | 
|  5432   // is enabled wrapper function will be called and we need to pass |  5422   // is enabled wrapper function will be called and we need to pass | 
|  5433   // address of the callback as additional parameter, always allocate |  5423   // address of the callback as additional parameter, always allocate | 
|  5434   // space for it. |  5424   // space for it. | 
|  5435   const int kApiArgc = 1 + 1; |  5425   const int kApiArgc = 1 + 1; | 
|  5436  |  5426  | 
|  5437   // Allocate the v8::Arguments structure in the arguments' space since |  5427   // Allocate the v8::Arguments structure in the arguments' space since | 
|  5438   // it's not controlled by GC. |  5428   // it's not controlled by GC. | 
|  5439   const int kApiStackSpace = 4; |  5429   const int kApiStackSpace = 4; | 
|  5440  |  5430  | 
|  5441   PrepareCallApiFunction(masm, kApiArgc + kApiStackSpace); |  5431   PrepareCallApiFunction(masm, kApiArgc + kApiStackSpace); | 
|  5442  |  5432  | 
|  5443   // FunctionCallbackInfo::implicit_args_. |  5433   // FunctionCallbackInfo::implicit_args_. | 
|  5444   __ mov(ApiParameterOperand(2), scratch); |  5434   __ mov(ApiParameterOperand(2), scratch); | 
|  5445   if (argc.is_immediate()) { |  5435   __ add(scratch, Immediate((argc() + FCA::kArgsLength - 1) * kPointerSize)); | 
|  5446     __ add(scratch, |  5436   // FunctionCallbackInfo::values_. | 
|  5447            Immediate((argc.immediate() + FCA::kArgsLength - 1) * kPointerSize)); |  5437   __ mov(ApiParameterOperand(3), scratch); | 
|  5448     // FunctionCallbackInfo::values_. |  5438   // FunctionCallbackInfo::length_. | 
|  5449     __ mov(ApiParameterOperand(3), scratch); |  5439   __ Move(ApiParameterOperand(4), Immediate(argc)); | 
|  5450     // FunctionCallbackInfo::length_. |  5440   // FunctionCallbackInfo::is_construct_call_. | 
|  5451     __ Move(ApiParameterOperand(4), Immediate(argc.immediate())); |  5441   __ Move(ApiParameterOperand(5), Immediate(0)); | 
|  5452     // FunctionCallbackInfo::is_construct_call_. |  | 
|  5453     __ Move(ApiParameterOperand(5), Immediate(0)); |  | 
|  5454   } else { |  | 
|  5455     __ lea(scratch, Operand(scratch, argc.reg(), times_pointer_size, |  | 
|  5456                             (FCA::kArgsLength - 1) * kPointerSize)); |  | 
|  5457     // FunctionCallbackInfo::values_. |  | 
|  5458     __ mov(ApiParameterOperand(3), scratch); |  | 
|  5459     // FunctionCallbackInfo::length_. |  | 
|  5460     __ mov(ApiParameterOperand(4), argc.reg()); |  | 
|  5461     // FunctionCallbackInfo::is_construct_call_. |  | 
|  5462     __ lea(argc.reg(), Operand(argc.reg(), times_pointer_size, |  | 
|  5463                                (FCA::kArgsLength + 1) * kPointerSize)); |  | 
|  5464     __ mov(ApiParameterOperand(5), argc.reg()); |  | 
|  5465   } |  | 
|  5466  |  5442  | 
|  5467   // v8::InvocationCallback's argument. |  5443   // v8::InvocationCallback's argument. | 
|  5468   __ lea(scratch, ApiParameterOperand(2)); |  5444   __ lea(scratch, ApiParameterOperand(2)); | 
|  5469   __ mov(ApiParameterOperand(0), scratch); |  5445   __ mov(ApiParameterOperand(0), scratch); | 
|  5470  |  5446  | 
|  5471   ExternalReference thunk_ref = |  5447   ExternalReference thunk_ref = | 
|  5472       ExternalReference::invoke_function_callback(masm->isolate()); |  5448       ExternalReference::invoke_function_callback(masm->isolate()); | 
|  5473  |  5449  | 
|  5474   Operand context_restore_operand(ebp, |  5450   Operand context_restore_operand(ebp, | 
|  5475                                   (2 + FCA::kContextSaveIndex) * kPointerSize); |  5451                                   (2 + FCA::kContextSaveIndex) * kPointerSize); | 
|  5476   // Stores return the first js argument |  5452   // Stores return the first js argument | 
|  5477   int return_value_offset = 0; |  5453   int return_value_offset = 0; | 
|  5478   if (return_first_arg) { |  5454   if (is_store()) { | 
|  5479     return_value_offset = 2 + FCA::kArgsLength; |  5455     return_value_offset = 2 + FCA::kArgsLength; | 
|  5480   } else { |  5456   } else { | 
|  5481     return_value_offset = 2 + FCA::kReturnValueOffset; |  5457     return_value_offset = 2 + FCA::kReturnValueOffset; | 
|  5482   } |  5458   } | 
|  5483   Operand return_value_operand(ebp, return_value_offset * kPointerSize); |  5459   Operand return_value_operand(ebp, return_value_offset * kPointerSize); | 
|  5484   int stack_space = 0; |  5460   int stack_space = 0; | 
|  5485   Operand is_construct_call_operand = ApiParameterOperand(5); |  5461   Operand is_construct_call_operand = ApiParameterOperand(5); | 
|  5486   Operand* stack_space_operand = &is_construct_call_operand; |  5462   Operand* stack_space_operand = &is_construct_call_operand; | 
|  5487   if (argc.is_immediate()) { |  5463   stack_space = argc() + FCA::kArgsLength + 1; | 
|  5488     stack_space = argc.immediate() + FCA::kArgsLength + 1; |  5464   stack_space_operand = nullptr; | 
|  5489     stack_space_operand = nullptr; |  | 
|  5490   } |  | 
|  5491   CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, |  5465   CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, | 
|  5492                            ApiParameterOperand(1), stack_space, |  5466                            ApiParameterOperand(1), stack_space, | 
|  5493                            stack_space_operand, return_value_operand, |  5467                            stack_space_operand, return_value_operand, | 
|  5494                            &context_restore_operand); |  5468                            &context_restore_operand); | 
|  5495 } |  5469 } | 
|  5496  |  5470  | 
|  5497  |  5471  | 
|  5498 void CallApiFunctionStub::Generate(MacroAssembler* masm) { |  | 
|  5499   bool call_data_undefined = this->call_data_undefined(); |  | 
|  5500   CallApiFunctionStubHelper(masm, ParameterCount(eax), false, |  | 
|  5501                             call_data_undefined, false); |  | 
|  5502 } |  | 
|  5503  |  | 
|  5504  |  | 
|  5505 void CallApiAccessorStub::Generate(MacroAssembler* masm) { |  | 
|  5506   bool is_store = this->is_store(); |  | 
|  5507   int argc = this->argc(); |  | 
|  5508   bool call_data_undefined = this->call_data_undefined(); |  | 
|  5509   bool is_lazy = this->is_lazy(); |  | 
|  5510   CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store, |  | 
|  5511                             call_data_undefined, is_lazy); |  | 
|  5512 } |  | 
|  5513  |  | 
|  5514  |  | 
|  5515 void CallApiGetterStub::Generate(MacroAssembler* masm) { |  5472 void CallApiGetterStub::Generate(MacroAssembler* masm) { | 
|  5516   // ----------- S t a t e ------------- |  5473   // ----------- S t a t e ------------- | 
|  5517   //  -- esp[0]                        : return address |  5474   //  -- esp[0]                        : return address | 
|  5518   //  -- esp[4]                        : name |  5475   //  -- esp[4]                        : name | 
|  5519   //  -- esp[8 .. (8 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_ |  5476   //  -- esp[8 .. (8 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_ | 
|  5520   //  -- ... |  5477   //  -- ... | 
|  5521   //  -- edx                           : api_function_address |  5478   //  -- edx                           : api_function_address | 
|  5522   // ----------------------------------- |  5479   // ----------------------------------- | 
|  5523   DCHECK(edx.is(ApiGetterDescriptor::function_address())); |  5480   DCHECK(edx.is(ApiGetterDescriptor::function_address())); | 
|  5524  |  5481  | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5560                            return_value_operand, NULL); |  5517                            return_value_operand, NULL); | 
|  5561 } |  5518 } | 
|  5562  |  5519  | 
|  5563  |  5520  | 
|  5564 #undef __ |  5521 #undef __ | 
|  5565  |  5522  | 
|  5566 }  // namespace internal |  5523 }  // namespace internal | 
|  5567 }  // namespace v8 |  5524 }  // namespace v8 | 
|  5568  |  5525  | 
|  5569 #endif  // V8_TARGET_ARCH_X87 |  5526 #endif  // V8_TARGET_ARCH_X87 | 
| OLD | NEW |