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 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 // -- esp[4] - esp[28] : FunctionCallbackInfo, incl. | 465 // -- esp[4] - esp[28] : FunctionCallbackInfo, incl. |
466 // : object passing the type check | 466 // : object passing the type check |
467 // (set by CheckPrototypes) | 467 // (set by CheckPrototypes) |
468 // -- esp[32] : last argument | 468 // -- esp[32] : last argument |
469 // -- ... | 469 // -- ... |
470 // -- esp[(argc + 7) * 4] : first argument | 470 // -- esp[(argc + 7) * 4] : first argument |
471 // -- esp[(argc + 8) * 4] : receiver | 471 // -- esp[(argc + 8) * 4] : receiver |
472 // ----------------------------------- | 472 // ----------------------------------- |
473 | 473 |
474 typedef FunctionCallbackArguments FCA; | 474 typedef FunctionCallbackArguments FCA; |
| 475 const int kArgs = kFastApiCallArguments; |
475 // Save calling context. | 476 // Save calling context. |
476 __ mov(Operand(esp, (1 + FCA::kContextSaveIndex) * kPointerSize), esi); | 477 __ mov(Operand(esp, (kArgs + FCA::kContextSaveIndex) * kPointerSize), esi); |
477 | 478 |
478 // Get the function and setup the context. | 479 // Get the function and setup the context. |
479 Handle<JSFunction> function = optimization.constant_function(); | 480 Handle<JSFunction> function = optimization.constant_function(); |
480 __ LoadHeapObject(edi, function); | 481 __ LoadHeapObject(edi, function); |
481 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 482 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
482 | 483 |
483 // Construct the FunctionCallbackInfo. | 484 // Construct the FunctionCallbackInfo. |
484 __ mov(Operand(esp, (1 + FCA::kCalleeIndex) * kPointerSize), edi); | 485 __ mov(Operand(esp, (kArgs + FCA::kCalleeIndex) * kPointerSize), edi); |
485 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 486 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
486 Handle<Object> call_data(api_call_info->data(), masm->isolate()); | 487 Handle<Object> call_data(api_call_info->data(), masm->isolate()); |
487 if (masm->isolate()->heap()->InNewSpace(*call_data)) { | 488 if (masm->isolate()->heap()->InNewSpace(*call_data)) { |
488 __ mov(ecx, api_call_info); | 489 __ mov(ecx, api_call_info); |
489 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); | 490 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); |
490 __ mov(Operand(esp, (1 + FCA::kDataIndex) * kPointerSize), ebx); | 491 __ mov(Operand(esp, (kArgs + FCA::kDataIndex) * kPointerSize), ebx); |
491 } else { | 492 } else { |
492 __ mov(Operand(esp, (1 + FCA::kDataIndex) * kPointerSize), | 493 __ mov(Operand(esp, (kArgs + FCA::kDataIndex) * kPointerSize), |
493 Immediate(call_data)); | 494 Immediate(call_data)); |
494 } | 495 } |
495 __ mov(Operand(esp, (1 + FCA::kIsolateIndex) * kPointerSize), | 496 __ mov(Operand(esp, (kArgs + FCA::kIsolateIndex) * kPointerSize), |
496 Immediate(reinterpret_cast<int>(masm->isolate()))); | 497 Immediate(reinterpret_cast<int>(masm->isolate()))); |
497 __ mov(Operand(esp, (1 + FCA::kReturnValueOffset) * kPointerSize), | 498 __ mov(Operand(esp, (kArgs + FCA::kReturnValueOffset) * kPointerSize), |
498 masm->isolate()->factory()->undefined_value()); | 499 masm->isolate()->factory()->undefined_value()); |
499 __ mov(Operand(esp, (1 + FCA::kReturnValueDefaultValueIndex) * kPointerSize), | 500 __ mov( |
500 masm->isolate()->factory()->undefined_value()); | 501 Operand(esp, (kArgs + FCA::kReturnValueDefaultValueIndex) * kPointerSize), |
| 502 masm->isolate()->factory()->undefined_value()); |
501 | 503 |
502 // Prepare arguments. | 504 // Prepare arguments. |
503 STATIC_ASSERT(kFastApiCallArguments == 7); | 505 STATIC_ASSERT(kArgs == 7); |
504 __ lea(eax, Operand(esp, 1 * kPointerSize)); | 506 __ lea(eax, Operand(esp, kArgs * kPointerSize)); |
| 507 |
505 | 508 |
506 // API function gets reference to the v8::Arguments. If CPU profiler | 509 // API function gets reference to the v8::Arguments. If CPU profiler |
507 // is enabled wrapper function will be called and we need to pass | 510 // is enabled wrapper function will be called and we need to pass |
508 // address of the callback as additional parameter, always allocate | 511 // address of the callback as additional parameter, always allocate |
509 // space for it. | 512 // space for it. |
510 const int kApiArgc = 1 + 1; | 513 const int kApiArgc = 1 + 1; |
511 | 514 |
512 // Allocate the v8::Arguments structure in the arguments' space since | 515 // Allocate the v8::Arguments structure in the arguments' space since |
513 // it's not controlled by GC. | 516 // it's not controlled by GC. |
514 const int kApiStackSpace = 4; | 517 const int kApiStackSpace = 4; |
515 | 518 |
516 // Function address is a foreign pointer outside V8's heap. | 519 // Function address is a foreign pointer outside V8's heap. |
517 Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 520 Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
518 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); | 521 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); |
519 | 522 |
520 // FunctionCallbackInfo::implicit_args_. | 523 // v8::Arguments::implicit_args_. |
521 __ mov(ApiParameterOperand(2), eax); | 524 __ mov(ApiParameterOperand(2), eax); |
522 __ add(eax, Immediate((argc + kFastApiCallArguments - 1) * kPointerSize)); | 525 __ add(eax, Immediate(argc * kPointerSize)); |
523 // FunctionCallbackInfo::values_. | 526 // v8::Arguments::values_. |
524 __ mov(ApiParameterOperand(3), eax); | 527 __ mov(ApiParameterOperand(3), eax); |
525 // FunctionCallbackInfo::length_. | 528 // v8::Arguments::length_. |
526 __ Set(ApiParameterOperand(4), Immediate(argc)); | 529 __ Set(ApiParameterOperand(4), Immediate(argc)); |
527 // FunctionCallbackInfo::is_construct_call_. | 530 // v8::Arguments::is_construct_call_. |
528 __ Set(ApiParameterOperand(5), Immediate(0)); | 531 __ Set(ApiParameterOperand(5), Immediate(0)); |
529 | 532 |
530 // v8::InvocationCallback's argument. | 533 // v8::InvocationCallback's argument. |
531 __ lea(eax, ApiParameterOperand(2)); | 534 __ lea(eax, ApiParameterOperand(2)); |
532 __ mov(ApiParameterOperand(0), eax); | 535 __ mov(ApiParameterOperand(0), eax); |
533 | 536 |
534 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); | 537 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); |
535 | 538 |
536 Operand context_restore_operand(ebp, | 539 Operand context_restore_operand( |
537 (2 + FCA::kContextSaveIndex) * kPointerSize); | 540 ebp, (kArgs + 1 + FCA::kContextSaveIndex) * kPointerSize); |
538 Operand return_value_operand(ebp, | 541 Operand return_value_operand( |
539 (2 + FCA::kReturnValueOffset) * kPointerSize); | 542 ebp, (kArgs + 1 + FCA::kReturnValueOffset) * kPointerSize); |
540 __ CallApiFunctionAndReturn(function_address, | 543 __ CallApiFunctionAndReturn(function_address, |
541 thunk_address, | 544 thunk_address, |
542 ApiParameterOperand(1), | 545 ApiParameterOperand(1), |
543 argc + kFastApiCallArguments + 1, | 546 argc + kArgs + 1, |
544 return_value_operand, | 547 return_value_operand, |
545 restore_context ? | 548 restore_context ? |
546 &context_restore_operand : NULL); | 549 &context_restore_operand : NULL); |
547 } | 550 } |
548 | 551 |
549 | 552 |
550 // Generate call to api function. | 553 // Generate call to api function. |
551 static void GenerateFastApiCall(MacroAssembler* masm, | 554 static void GenerateFastApiCall(MacroAssembler* masm, |
552 const CallOptimization& optimization, | 555 const CallOptimization& optimization, |
553 Register receiver, | 556 Register receiver, |
554 Register scratch, | 557 Register scratch, |
555 int argc, | 558 int argc, |
556 Register* values) { | 559 Register* values) { |
557 ASSERT(optimization.is_simple_api_call()); | 560 ASSERT(optimization.is_simple_api_call()); |
558 ASSERT(!receiver.is(scratch)); | 561 ASSERT(!receiver.is(scratch)); |
559 | 562 |
560 const int stack_space = kFastApiCallArguments + argc + 1; | 563 const int stack_space = kFastApiCallArguments + argc + 1; |
561 const int kHolderIndex = FunctionCallbackArguments::kHolderIndex + 1; | 564 const int kHolderIndex = kFastApiCallArguments + |
| 565 FunctionCallbackArguments::kHolderIndex; |
562 // Copy return value. | 566 // Copy return value. |
563 __ mov(scratch, Operand(esp, 0)); | 567 __ mov(scratch, Operand(esp, 0)); |
564 // Assign stack space for the call arguments. | 568 // Assign stack space for the call arguments. |
565 __ sub(esp, Immediate(stack_space * kPointerSize)); | 569 __ sub(esp, Immediate(stack_space * kPointerSize)); |
566 // Move the return address on top of the stack. | 570 // Move the return address on top of the stack. |
567 __ mov(Operand(esp, 0), scratch); | 571 __ mov(Operand(esp, 0), scratch); |
568 // Write holder to stack frame. | 572 // Write holder to stack frame. |
569 __ mov(Operand(esp, kHolderIndex * kPointerSize), receiver); | 573 __ mov(Operand(esp, kHolderIndex * kPointerSize), receiver); |
570 // Write receiver to stack frame. | 574 // Write receiver to stack frame. |
571 int index = stack_space; | 575 int index = stack_space; |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1156 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1160 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
1157 Register object_reg, | 1161 Register object_reg, |
1158 Handle<JSObject> holder, | 1162 Handle<JSObject> holder, |
1159 Register holder_reg, | 1163 Register holder_reg, |
1160 Register scratch1, | 1164 Register scratch1, |
1161 Register scratch2, | 1165 Register scratch2, |
1162 Handle<Name> name, | 1166 Handle<Name> name, |
1163 int save_at_depth, | 1167 int save_at_depth, |
1164 Label* miss, | 1168 Label* miss, |
1165 PrototypeCheckType check) { | 1169 PrototypeCheckType check) { |
1166 const int kHolderIndex = FunctionCallbackArguments::kHolderIndex + 1; | 1170 const int kHolderIndex = kFastApiCallArguments + |
| 1171 FunctionCallbackArguments::kHolderIndex; |
1167 // Make sure that the type feedback oracle harvests the receiver map. | 1172 // Make sure that the type feedback oracle harvests the receiver map. |
1168 // TODO(svenpanne) Remove this hack when all ICs are reworked. | 1173 // TODO(svenpanne) Remove this hack when all ICs are reworked. |
1169 __ mov(scratch1, Handle<Map>(object->map())); | 1174 __ mov(scratch1, Handle<Map>(object->map())); |
1170 | 1175 |
1171 Handle<JSObject> first = object; | 1176 Handle<JSObject> first = object; |
1172 // Make sure there's no overlap between holder and object registers. | 1177 // Make sure there's no overlap between holder and object registers. |
1173 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1178 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
1174 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1179 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
1175 && !scratch2.is(scratch1)); | 1180 && !scratch2.is(scratch1)); |
1176 | 1181 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1401 } | 1406 } |
1402 | 1407 |
1403 | 1408 |
1404 void BaseLoadStubCompiler::GenerateLoadCallback( | 1409 void BaseLoadStubCompiler::GenerateLoadCallback( |
1405 Register reg, | 1410 Register reg, |
1406 Handle<ExecutableAccessorInfo> callback) { | 1411 Handle<ExecutableAccessorInfo> callback) { |
1407 // Insert additional parameters into the stack frame above return address. | 1412 // Insert additional parameters into the stack frame above return address. |
1408 ASSERT(!scratch3().is(reg)); | 1413 ASSERT(!scratch3().is(reg)); |
1409 __ pop(scratch3()); // Get return address to place it below. | 1414 __ pop(scratch3()); // Get return address to place it below. |
1410 | 1415 |
1411 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); | 1416 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 0); |
1412 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); | 1417 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == -1); |
1413 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); | 1418 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == -2); |
1414 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); | 1419 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == -3); |
1415 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); | 1420 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == -4); |
1416 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); | 1421 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == -5); |
1417 __ push(receiver()); // receiver | 1422 __ push(receiver()); // receiver |
| 1423 __ mov(scratch2(), esp); |
| 1424 ASSERT(!scratch2().is(reg)); |
1418 // Push data from ExecutableAccessorInfo. | 1425 // Push data from ExecutableAccessorInfo. |
1419 if (isolate()->heap()->InNewSpace(callback->data())) { | 1426 if (isolate()->heap()->InNewSpace(callback->data())) { |
1420 ASSERT(!scratch2().is(reg)); | 1427 Register scratch = reg.is(scratch1()) ? receiver() : scratch1(); |
1421 __ mov(scratch2(), Immediate(callback)); | 1428 __ mov(scratch, Immediate(callback)); |
1422 __ push(FieldOperand(scratch2(), ExecutableAccessorInfo::kDataOffset)); | 1429 __ push(FieldOperand(scratch, ExecutableAccessorInfo::kDataOffset)); |
1423 } else { | 1430 } else { |
1424 __ push(Immediate(Handle<Object>(callback->data(), isolate()))); | 1431 __ push(Immediate(Handle<Object>(callback->data(), isolate()))); |
1425 } | 1432 } |
1426 __ push(Immediate(isolate()->factory()->undefined_value())); // ReturnValue | 1433 __ push(Immediate(isolate()->factory()->undefined_value())); // ReturnValue |
1427 // ReturnValue default value | 1434 // ReturnValue default value |
1428 __ push(Immediate(isolate()->factory()->undefined_value())); | 1435 __ push(Immediate(isolate()->factory()->undefined_value())); |
1429 __ push(Immediate(reinterpret_cast<int>(isolate()))); | 1436 __ push(Immediate(reinterpret_cast<int>(isolate()))); |
1430 __ push(reg); // holder | 1437 __ push(reg); // holder |
1431 | 1438 |
1432 // Save a pointer to where we pushed the arguments. This will be | 1439 // Save a pointer to where we pushed the arguments pointer. This will be |
1433 // passed as the const PropertyAccessorInfo& to the C++ callback. | 1440 // passed as the const ExecutableAccessorInfo& to the C++ callback. |
1434 __ push(esp); | 1441 __ push(scratch2()); |
1435 | 1442 |
1436 __ push(name()); // name | 1443 __ push(name()); // name |
1437 __ mov(ebx, esp); // esp points to reference to name (handler). | 1444 __ mov(ebx, esp); // esp points to reference to name (handler). |
1438 | 1445 |
1439 __ push(scratch3()); // Restore return address. | 1446 __ push(scratch3()); // Restore return address. |
1440 | 1447 |
1441 // array for v8::Arguments::values_, handler for name and pointer | 1448 // array for v8::Arguments::values_, handler for name and pointer |
1442 // to the values (it considered as smi in GC). | 1449 // to the values (it considered as smi in GC). |
1443 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2; | 1450 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2; |
1444 // Allocate space for opional callback address parameter in case | 1451 // Allocate space for opional callback address parameter in case |
(...skipping 1826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3271 // ----------------------------------- | 3278 // ----------------------------------- |
3272 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); | 3279 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); |
3273 } | 3280 } |
3274 | 3281 |
3275 | 3282 |
3276 #undef __ | 3283 #undef __ |
3277 | 3284 |
3278 } } // namespace v8::internal | 3285 } } // namespace v8::internal |
3279 | 3286 |
3280 #endif // V8_TARGET_ARCH_IA32 | 3287 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |