OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 Handle<JSObject> holder_obj) { | 411 Handle<JSObject> holder_obj) { |
412 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 412 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); |
413 __ CallExternalReference( | 413 __ CallExternalReference( |
414 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), | 414 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), |
415 masm->isolate()), | 415 masm->isolate()), |
416 6); | 416 6); |
417 } | 417 } |
418 | 418 |
419 | 419 |
420 // Number of pointers to be reserved on stack for fast API call. | 420 // Number of pointers to be reserved on stack for fast API call. |
421 static const int kFastApiCallArguments = 4; | 421 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; |
422 | 422 |
423 | 423 |
424 // Reserves space for the extra arguments to API function in the | 424 // Reserves space for the extra arguments to API function in the |
425 // caller's frame. | 425 // caller's frame. |
426 // | 426 // |
427 // These arguments are set by CheckPrototypes and GenerateFastApiCall. | 427 // These arguments are set by CheckPrototypes and GenerateFastApiCall. |
428 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { | 428 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { |
429 // ----------- S t a t e ------------- | 429 // ----------- S t a t e ------------- |
430 // -- esp[0] : return address | 430 // -- esp[0] : return address |
431 // -- esp[4] : last argument in the internal frame of the caller | 431 // -- esp[4] : last argument in the internal frame of the caller |
(...skipping 28 matching lines...) Expand all Loading... |
460 int argc) { | 460 int argc) { |
461 // ----------- S t a t e ------------- | 461 // ----------- S t a t e ------------- |
462 // -- esp[0] : return address | 462 // -- esp[0] : return address |
463 // -- esp[4] : object passing the type check | 463 // -- esp[4] : object passing the type check |
464 // (last fast api call extra argument, | 464 // (last fast api call extra argument, |
465 // set by CheckPrototypes) | 465 // set by CheckPrototypes) |
466 // -- esp[8] : api function | 466 // -- esp[8] : api function |
467 // (first fast api call extra argument) | 467 // (first fast api call extra argument) |
468 // -- esp[12] : api call data | 468 // -- esp[12] : api call data |
469 // -- esp[16] : isolate | 469 // -- esp[16] : isolate |
470 // -- esp[20] : last argument | 470 // -- esp[20] : ReturnValue |
| 471 // -- esp[24] : last argument |
471 // -- ... | 472 // -- ... |
472 // -- esp[(argc + 4) * 4] : first argument | 473 // -- esp[(argc + 5) * 4] : first argument |
473 // -- esp[(argc + 5) * 4] : receiver | 474 // -- esp[(argc + 6) * 4] : receiver |
474 // ----------------------------------- | 475 // ----------------------------------- |
475 // Get the function and setup the context. | 476 // Get the function and setup the context. |
476 Handle<JSFunction> function = optimization.constant_function(); | 477 Handle<JSFunction> function = optimization.constant_function(); |
477 __ LoadHeapObject(edi, function); | 478 __ LoadHeapObject(edi, function); |
478 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 479 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
479 | 480 |
480 // Pass the additional arguments. | 481 // Pass the additional arguments. |
481 __ mov(Operand(esp, 2 * kPointerSize), edi); | 482 __ mov(Operand(esp, 2 * kPointerSize), edi); |
482 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 483 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
483 Handle<Object> call_data(api_call_info->data(), masm->isolate()); | 484 Handle<Object> call_data(api_call_info->data(), masm->isolate()); |
484 if (masm->isolate()->heap()->InNewSpace(*call_data)) { | 485 if (masm->isolate()->heap()->InNewSpace(*call_data)) { |
485 __ mov(ecx, api_call_info); | 486 __ mov(ecx, api_call_info); |
486 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); | 487 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); |
487 __ mov(Operand(esp, 3 * kPointerSize), ebx); | 488 __ mov(Operand(esp, 3 * kPointerSize), ebx); |
488 } else { | 489 } else { |
489 __ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data)); | 490 __ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data)); |
490 } | 491 } |
491 __ mov(Operand(esp, 4 * kPointerSize), | 492 __ mov(Operand(esp, 4 * kPointerSize), |
492 Immediate(reinterpret_cast<int>(masm->isolate()))); | 493 Immediate(reinterpret_cast<int>(masm->isolate()))); |
| 494 __ mov(Operand(esp, 5 * kPointerSize), |
| 495 masm->isolate()->factory()->undefined_value()); |
493 | 496 |
494 // Prepare arguments. | 497 // Prepare arguments. |
495 __ lea(eax, Operand(esp, 4 * kPointerSize)); | 498 STATIC_ASSERT(kFastApiCallArguments == 5); |
| 499 __ lea(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); |
496 | 500 |
497 const int kApiArgc = 1; // API function gets reference to the v8::Arguments. | 501 const int kApiArgc = 1; // API function gets reference to the v8::Arguments. |
498 | 502 |
499 // Allocate the v8::Arguments structure in the arguments' space since | 503 // Allocate the v8::Arguments structure in the arguments' space since |
500 // it's not controlled by GC. | 504 // it's not controlled by GC. |
501 const int kApiStackSpace = 4; | 505 const int kApiStackSpace = 4; |
502 | 506 |
503 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); | 507 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); |
504 | 508 |
505 __ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_. | 509 __ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_. |
506 __ add(eax, Immediate(argc * kPointerSize)); | 510 __ add(eax, Immediate(argc * kPointerSize)); |
507 __ mov(ApiParameterOperand(2), eax); // v8::Arguments::values_. | 511 __ mov(ApiParameterOperand(2), eax); // v8::Arguments::values_. |
508 __ Set(ApiParameterOperand(3), Immediate(argc)); // v8::Arguments::length_. | 512 __ Set(ApiParameterOperand(3), Immediate(argc)); // v8::Arguments::length_. |
509 // v8::Arguments::is_construct_call_. | 513 // v8::Arguments::is_construct_call_. |
510 __ Set(ApiParameterOperand(4), Immediate(0)); | 514 __ Set(ApiParameterOperand(4), Immediate(0)); |
511 | 515 |
512 // v8::InvocationCallback's argument. | 516 // v8::InvocationCallback's argument. |
513 __ lea(eax, ApiParameterOperand(1)); | 517 __ lea(eax, ApiParameterOperand(1)); |
514 __ mov(ApiParameterOperand(0), eax); | 518 __ mov(ApiParameterOperand(0), eax); |
515 | 519 |
516 // Function address is a foreign pointer outside V8's heap. | 520 // Function address is a foreign pointer outside V8's heap. |
517 Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 521 Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
518 __ CallApiFunctionAndReturn(function_address, | 522 __ CallApiFunctionAndReturn(function_address, |
519 argc + kFastApiCallArguments + 1); | 523 argc + kFastApiCallArguments + 1, |
| 524 16); // TODO(dcarney): compute this somehow |
520 } | 525 } |
521 | 526 |
522 | 527 |
523 class CallInterceptorCompiler BASE_EMBEDDED { | 528 class CallInterceptorCompiler BASE_EMBEDDED { |
524 public: | 529 public: |
525 CallInterceptorCompiler(StubCompiler* stub_compiler, | 530 CallInterceptorCompiler(StubCompiler* stub_compiler, |
526 const ParameterCount& arguments, | 531 const ParameterCount& arguments, |
527 Register name, | 532 Register name, |
528 Code::ExtraICState extra_state) | 533 Code::ExtraICState extra_state) |
529 : stub_compiler_(stub_compiler), | 534 : stub_compiler_(stub_compiler), |
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1216 ASSERT(!scratch2().is(reg)); | 1221 ASSERT(!scratch2().is(reg)); |
1217 __ push(reg); // holder | 1222 __ push(reg); // holder |
1218 // Push data from ExecutableAccessorInfo. | 1223 // Push data from ExecutableAccessorInfo. |
1219 if (isolate()->heap()->InNewSpace(callback->data())) { | 1224 if (isolate()->heap()->InNewSpace(callback->data())) { |
1220 __ mov(scratch1(), Immediate(callback)); | 1225 __ mov(scratch1(), Immediate(callback)); |
1221 __ push(FieldOperand(scratch1(), ExecutableAccessorInfo::kDataOffset)); | 1226 __ push(FieldOperand(scratch1(), ExecutableAccessorInfo::kDataOffset)); |
1222 } else { | 1227 } else { |
1223 __ push(Immediate(Handle<Object>(callback->data(), isolate()))); | 1228 __ push(Immediate(Handle<Object>(callback->data(), isolate()))); |
1224 } | 1229 } |
1225 __ push(Immediate(reinterpret_cast<int>(isolate()))); | 1230 __ push(Immediate(reinterpret_cast<int>(isolate()))); |
| 1231 __ push(Immediate(isolate()->factory()->undefined_value())); // ReturnValue |
1226 | 1232 |
1227 // Save a pointer to where we pushed the arguments pointer. This will be | 1233 // Save a pointer to where we pushed the arguments pointer. This will be |
1228 // passed as the const ExecutableAccessorInfo& to the C++ callback. | 1234 // passed as the const ExecutableAccessorInfo& to the C++ callback. |
1229 __ push(scratch2()); | 1235 __ push(scratch2()); |
1230 | 1236 |
1231 __ push(name()); // name | 1237 __ push(name()); // name |
1232 __ mov(ebx, esp); // esp points to reference to name (handler). | 1238 __ mov(ebx, esp); // esp points to reference to name (handler). |
1233 | 1239 |
1234 __ push(scratch3()); // Restore return address. | 1240 __ push(scratch3()); // Restore return address. |
1235 | 1241 |
1236 // 4 elements array for v8::Arguments::values_, handler for name and pointer | 1242 // array for v8::Arguments::values_, handler for name and pointer |
1237 // to the values (it considered as smi in GC). | 1243 // to the values (it considered as smi in GC). |
1238 const int kStackSpace = 6; | 1244 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2; |
1239 const int kApiArgc = 2; | 1245 const int kApiArgc = 2; |
1240 | 1246 |
1241 __ PrepareCallApiFunction(kApiArgc); | 1247 __ PrepareCallApiFunction(kApiArgc); |
1242 __ mov(ApiParameterOperand(0), ebx); // name. | 1248 __ mov(ApiParameterOperand(0), ebx); // name. |
1243 __ add(ebx, Immediate(kPointerSize)); | 1249 __ add(ebx, Immediate(kPointerSize)); |
1244 __ mov(ApiParameterOperand(1), ebx); // arguments pointer. | 1250 __ mov(ApiParameterOperand(1), ebx); // arguments pointer. |
1245 | 1251 |
1246 // Emitting a stub call may try to allocate (if the code is not | 1252 // Emitting a stub call may try to allocate (if the code is not |
1247 // already generated). Do not allow the assembler to perform a | 1253 // already generated). Do not allow the assembler to perform a |
1248 // garbage collection but instead return the allocation failure | 1254 // garbage collection but instead return the allocation failure |
1249 // object. | 1255 // object. |
1250 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1256 Address getter_address = v8::ToCData<Address>(callback->getter()); |
1251 __ CallApiFunctionAndReturn(getter_address, kStackSpace); | 1257 __ CallApiFunctionAndReturn(getter_address, |
| 1258 kStackSpace, |
| 1259 8); // TODO(dcarney): compute this somehow |
1252 } | 1260 } |
1253 | 1261 |
1254 | 1262 |
1255 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) { | 1263 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) { |
1256 // Return the constant value. | 1264 // Return the constant value. |
1257 __ LoadHeapObject(eax, value); | 1265 __ LoadHeapObject(eax, value); |
1258 __ ret(0); | 1266 __ ret(0); |
1259 } | 1267 } |
1260 | 1268 |
1261 | 1269 |
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2342 | 2350 |
2343 // Allocate space for v8::Arguments implicit values. Must be initialized | 2351 // Allocate space for v8::Arguments implicit values. Must be initialized |
2344 // before calling any runtime function. | 2352 // before calling any runtime function. |
2345 __ sub(esp, Immediate(kFastApiCallArguments * kPointerSize)); | 2353 __ sub(esp, Immediate(kFastApiCallArguments * kPointerSize)); |
2346 | 2354 |
2347 // Check that the maps haven't changed and find a Holder as a side effect. | 2355 // Check that the maps haven't changed and find a Holder as a side effect. |
2348 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, | 2356 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, |
2349 name, depth, &miss); | 2357 name, depth, &miss); |
2350 | 2358 |
2351 // Move the return address on top of the stack. | 2359 // Move the return address on top of the stack. |
2352 __ mov(eax, Operand(esp, 4 * kPointerSize)); | 2360 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); |
2353 __ mov(Operand(esp, 0 * kPointerSize), eax); | 2361 __ mov(Operand(esp, 0 * kPointerSize), eax); |
2354 | 2362 |
2355 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains | 2363 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains |
2356 // duplicate of return address and will be overwritten. | 2364 // duplicate of return address and will be overwritten. |
2357 GenerateFastApiCall(masm(), optimization, argc); | 2365 GenerateFastApiCall(masm(), optimization, argc); |
2358 | 2366 |
2359 __ bind(&miss); | 2367 __ bind(&miss); |
2360 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); | 2368 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); |
2361 | 2369 |
2362 __ bind(&miss_before_stack_reserved); | 2370 __ bind(&miss_before_stack_reserved); |
(...skipping 1335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3698 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3706 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
3699 } | 3707 } |
3700 } | 3708 } |
3701 | 3709 |
3702 | 3710 |
3703 #undef __ | 3711 #undef __ |
3704 | 3712 |
3705 } } // namespace v8::internal | 3713 } } // namespace v8::internal |
3706 | 3714 |
3707 #endif // V8_TARGET_ARCH_IA32 | 3715 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |