| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 Object* callback = optimization.api_call_info()->callback(); | 492 Object* callback = optimization.api_call_info()->callback(); |
| 493 Address api_function_address = v8::ToCData<Address>(callback); | 493 Address api_function_address = v8::ToCData<Address>(callback); |
| 494 ApiFunction fun(api_function_address); | 494 ApiFunction fun(api_function_address); |
| 495 | 495 |
| 496 const int kApiArgc = 1; // API function gets reference to the v8::Arguments. | 496 const int kApiArgc = 1; // API function gets reference to the v8::Arguments. |
| 497 | 497 |
| 498 // Allocate the v8::Arguments structure in the arguments' space since | 498 // Allocate the v8::Arguments structure in the arguments' space since |
| 499 // it's not controlled by GC. | 499 // it's not controlled by GC. |
| 500 const int kApiStackSpace = 4; | 500 const int kApiStackSpace = 4; |
| 501 | 501 |
| 502 __ PrepareCallApiFunction(argc + kFastApiCallArguments + 1, | 502 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace, ebx); |
| 503 kApiArgc + kApiStackSpace); | |
| 504 | 503 |
| 505 __ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_. | 504 __ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_. |
| 506 __ add(Operand(eax), Immediate(argc * kPointerSize)); | 505 __ add(Operand(eax), Immediate(argc * kPointerSize)); |
| 507 __ mov(ApiParameterOperand(2), eax); // v8::Arguments::values_. | 506 __ mov(ApiParameterOperand(2), eax); // v8::Arguments::values_. |
| 508 __ Set(ApiParameterOperand(3), Immediate(argc)); // v8::Arguments::length_. | 507 __ Set(ApiParameterOperand(3), Immediate(argc)); // v8::Arguments::length_. |
| 509 // v8::Arguments::is_construct_call_. | 508 // v8::Arguments::is_construct_call_. |
| 510 __ mov(ApiParameterOperand(4), Immediate(0)); | 509 __ mov(ApiParameterOperand(4), Immediate(0)); |
| 511 | 510 |
| 512 // v8::InvocationCallback's argument. | 511 // v8::InvocationCallback's argument. |
| 513 __ lea(eax, ApiParameterOperand(1)); | 512 __ lea(eax, ApiParameterOperand(1)); |
| 514 __ mov(ApiParameterOperand(0), eax); | 513 __ mov(ApiParameterOperand(0), eax); |
| 515 | 514 |
| 516 // Emitting a stub call may try to allocate (if the code is not | 515 // Emitting a stub call may try to allocate (if the code is not |
| 517 // already generated). Do not allow the assembler to perform a | 516 // already generated). Do not allow the assembler to perform a |
| 518 // garbage collection but instead return the allocation failure | 517 // garbage collection but instead return the allocation failure |
| 519 // object. | 518 // object. |
| 520 MaybeObject* result = | 519 MaybeObject* result = |
| 521 masm->TryCallApiFunctionAndReturn(&fun, kApiArgc + kApiStackSpace); | 520 masm->TryCallApiFunctionAndReturn(&fun, argc + kFastApiCallArguments + 1); |
| 522 if (result->IsFailure()) { | 521 if (result->IsFailure()) { |
| 523 *failure = Failure::cast(result); | 522 *failure = Failure::cast(result); |
| 524 return false; | 523 return false; |
| 525 } | 524 } |
| 526 return true; | 525 return true; |
| 527 } | 526 } |
| 528 | 527 |
| 529 | 528 |
| 530 class CallInterceptorCompiler BASE_EMBEDDED { | 529 class CallInterceptorCompiler BASE_EMBEDDED { |
| 531 public: | 530 public: |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1102 | 1101 |
| 1103 // Do call through the api. | 1102 // Do call through the api. |
| 1104 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1103 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 1105 ApiFunction fun(getter_address); | 1104 ApiFunction fun(getter_address); |
| 1106 | 1105 |
| 1107 // 3 elements array for v8::Agruments::values_, handler for name and pointer | 1106 // 3 elements array for v8::Agruments::values_, handler for name and pointer |
| 1108 // to the values (it considered as smi in GC). | 1107 // to the values (it considered as smi in GC). |
| 1109 const int kStackSpace = 5; | 1108 const int kStackSpace = 5; |
| 1110 const int kApiArgc = 2; | 1109 const int kApiArgc = 2; |
| 1111 | 1110 |
| 1112 __ PrepareCallApiFunction(kStackSpace, kApiArgc); | 1111 __ PrepareCallApiFunction(kApiArgc, eax); |
| 1113 __ mov(ApiParameterOperand(0), ebx); // name. | 1112 __ mov(ApiParameterOperand(0), ebx); // name. |
| 1114 __ add(Operand(ebx), Immediate(kPointerSize)); | 1113 __ add(Operand(ebx), Immediate(kPointerSize)); |
| 1115 __ mov(ApiParameterOperand(1), ebx); // arguments pointer. | 1114 __ mov(ApiParameterOperand(1), ebx); // arguments pointer. |
| 1116 | 1115 |
| 1117 // Emitting a stub call may try to allocate (if the code is not | 1116 // Emitting a stub call may try to allocate (if the code is not |
| 1118 // already generated). Do not allow the assembler to perform a | 1117 // already generated). Do not allow the assembler to perform a |
| 1119 // garbage collection but instead return the allocation failure | 1118 // garbage collection but instead return the allocation failure |
| 1120 // object. | 1119 // object. |
| 1121 MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun, kApiArgc); | 1120 MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); |
| 1122 if (result->IsFailure()) { | 1121 if (result->IsFailure()) { |
| 1123 *failure = Failure::cast(result); | 1122 *failure = Failure::cast(result); |
| 1124 return false; | 1123 return false; |
| 1125 } | 1124 } |
| 1126 | 1125 |
| 1127 return true; | 1126 return true; |
| 1128 } | 1127 } |
| 1129 | 1128 |
| 1130 | 1129 |
| 1131 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1130 void StubCompiler::GenerateLoadConstant(JSObject* object, |
| (...skipping 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2162 case RECEIVER_MAP_CHECK: | 2161 case RECEIVER_MAP_CHECK: |
| 2163 __ IncrementCounter(&Counters::call_const, 1); | 2162 __ IncrementCounter(&Counters::call_const, 1); |
| 2164 | 2163 |
| 2165 if (optimization.is_simple_api_call() && !object->IsGlobalObject()) { | 2164 if (optimization.is_simple_api_call() && !object->IsGlobalObject()) { |
| 2166 depth = optimization.GetPrototypeDepthOfExpectedType( | 2165 depth = optimization.GetPrototypeDepthOfExpectedType( |
| 2167 JSObject::cast(object), holder); | 2166 JSObject::cast(object), holder); |
| 2168 } | 2167 } |
| 2169 | 2168 |
| 2170 if (depth != kInvalidProtoDepth) { | 2169 if (depth != kInvalidProtoDepth) { |
| 2171 __ IncrementCounter(&Counters::call_const_fast_api, 1); | 2170 __ IncrementCounter(&Counters::call_const_fast_api, 1); |
| 2172 ReserveSpaceForFastApiCall(masm(), eax); | 2171 |
| 2172 // Allocate space for v8::Arguments implicit values. Must be initialized |
| 2173 // before to call any runtime function. |
| 2174 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); |
| 2173 } | 2175 } |
| 2174 | 2176 |
| 2175 // Check that the maps haven't changed. | 2177 // Check that the maps haven't changed. |
| 2176 CheckPrototypes(JSObject::cast(object), edx, holder, | 2178 CheckPrototypes(JSObject::cast(object), edx, holder, |
| 2177 ebx, eax, edi, name, depth, &miss); | 2179 ebx, eax, edi, name, depth, &miss); |
| 2178 | 2180 |
| 2179 // Patch the receiver on the stack with the global proxy if | 2181 // Patch the receiver on the stack with the global proxy if |
| 2180 // necessary. | 2182 // necessary. |
| 2181 if (object->IsGlobalObject()) { | 2183 if (object->IsGlobalObject()) { |
| 2182 ASSERT(depth == kInvalidProtoDepth); | 2184 ASSERT(depth == kInvalidProtoDepth); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2242 } | 2244 } |
| 2243 break; | 2245 break; |
| 2244 } | 2246 } |
| 2245 | 2247 |
| 2246 default: | 2248 default: |
| 2247 UNREACHABLE(); | 2249 UNREACHABLE(); |
| 2248 } | 2250 } |
| 2249 | 2251 |
| 2250 if (depth != kInvalidProtoDepth) { | 2252 if (depth != kInvalidProtoDepth) { |
| 2251 Failure* failure; | 2253 Failure* failure; |
| 2254 // Move the return address on top of the stack. |
| 2255 __ mov(eax, Operand(esp, 3 * kPointerSize)); |
| 2256 __ mov(Operand(esp, 0 * kPointerSize), eax); |
| 2257 |
| 2258 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains |
| 2259 // duplicate of return address and will be overwritten. |
| 2252 bool success = GenerateFastApiCall(masm(), optimization, argc, &failure); | 2260 bool success = GenerateFastApiCall(masm(), optimization, argc, &failure); |
| 2253 if (!success) { | 2261 if (!success) { |
| 2254 return failure; | 2262 return failure; |
| 2255 } | 2263 } |
| 2256 } else { | 2264 } else { |
| 2257 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 2265 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
| 2258 } | 2266 } |
| 2259 | 2267 |
| 2260 // Handle call cache miss. | 2268 // Handle call cache miss. |
| 2261 __ bind(&miss); | 2269 __ bind(&miss); |
| 2262 if (depth != kInvalidProtoDepth) { | 2270 if (depth != kInvalidProtoDepth) { |
| 2263 FreeSpaceForFastApiCall(masm(), eax); | 2271 __ add(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); |
| 2264 } | 2272 } |
| 2265 __ bind(&miss_in_smi_check); | 2273 __ bind(&miss_in_smi_check); |
| 2266 Object* obj; | 2274 Object* obj; |
| 2267 { MaybeObject* maybe_obj = GenerateMissBranch(); | 2275 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 2268 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2276 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2269 } | 2277 } |
| 2270 | 2278 |
| 2271 // Return the generated code. | 2279 // Return the generated code. |
| 2272 return GetCode(function); | 2280 return GetCode(function); |
| 2273 } | 2281 } |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3147 // Return the generated code. | 3155 // Return the generated code. |
| 3148 return GetCode(); | 3156 return GetCode(); |
| 3149 } | 3157 } |
| 3150 | 3158 |
| 3151 | 3159 |
| 3152 #undef __ | 3160 #undef __ |
| 3153 | 3161 |
| 3154 } } // namespace v8::internal | 3162 } } // namespace v8::internal |
| 3155 | 3163 |
| 3156 #endif // V8_TARGET_ARCH_IA32 | 3164 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |