Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 23461039: add context save for GenerateFastApiCall (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 __ movq(scratch, StackOperandForReturnAddress(0)); 436 __ movq(scratch, StackOperandForReturnAddress(0));
437 __ movq(StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize), 437 __ movq(StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize),
438 scratch); 438 scratch);
439 __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments)); 439 __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments));
440 } 440 }
441 441
442 442
443 // Generates call to API function. 443 // Generates call to API function.
444 static void GenerateFastApiCall(MacroAssembler* masm, 444 static void GenerateFastApiCall(MacroAssembler* masm,
445 const CallOptimization& optimization, 445 const CallOptimization& optimization,
446 int argc) { 446 int argc,
447 bool restore_context) {
447 // ----------- S t a t e ------------- 448 // ----------- S t a t e -------------
448 // -- rsp[0] : return address 449 // -- rsp[0] : return address
449 // -- rsp[8] : object passing the type check 450 // -- rsp[8] : object passing the type check
450 // (last fast api call extra argument, 451 // (last fast api call extra argument,
451 // set by CheckPrototypes) 452 // set by CheckPrototypes)
452 // -- rsp[16] : api function 453 // -- rsp[16] : api function
453 // (first fast api call extra argument) 454 // (first fast api call extra argument)
454 // -- rsp[24] : api call data 455 // -- rsp[24] : api call data
455 // -- rsp[32] : isolate 456 // -- rsp[32] : context save
456 // -- rsp[40] : ReturnValue default value 457 // -- rsp[40] : isolate
457 // -- rsp[48] : ReturnValue 458 // -- rsp[48] : ReturnValue default value
459 // -- rsp[56] : ReturnValue
458 // 460 //
459 // -- rsp[56] : last argument 461 // -- rsp[64] : last argument
460 // -- ... 462 // -- ...
461 // -- rsp[(argc + 6) * 8] : first argument 463 // -- rsp[(argc + 7) * 8] : first argument
462 // -- rsp[(argc + 7) * 8] : receiver 464 // -- rsp[(argc + 8) * 8] : receiver
463 // ----------------------------------- 465 // -----------------------------------
464 // Get the function and setup the context.
465 Handle<JSFunction> function = optimization.constant_function();
466 __ LoadHeapObject(rdi, function);
467 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
468
469 int api_call_argc = argc + kFastApiCallArguments; 466 int api_call_argc = argc + kFastApiCallArguments;
470 StackArgumentsAccessor args(rsp, api_call_argc); 467 StackArgumentsAccessor args(rsp, api_call_argc);
471 468
472 // Pass the additional arguments. 469 // Pass the additional arguments.
473 __ movq(args.GetArgumentOperand(api_call_argc - 1), rdi); 470 __ movq(args.GetArgumentOperand(api_call_argc - 1), rdi);
Michael Starzinger 2013/09/12 18:38:51 Here $rdi does not yet contain the function to be
474 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 471 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
475 Handle<Object> call_data(api_call_info->data(), masm->isolate()); 472 Handle<Object> call_data(api_call_info->data(), masm->isolate());
476 if (masm->isolate()->heap()->InNewSpace(*call_data)) { 473 if (masm->isolate()->heap()->InNewSpace(*call_data)) {
477 __ Move(rcx, api_call_info); 474 __ Move(rcx, api_call_info);
478 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); 475 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
479 __ movq(args.GetArgumentOperand(api_call_argc - 2), rbx); 476 __ movq(args.GetArgumentOperand(api_call_argc - 2), rbx);
480 } else { 477 } else {
481 __ Move(args.GetArgumentOperand(api_call_argc - 2), call_data); 478 __ Move(args.GetArgumentOperand(api_call_argc - 2), call_data);
482 } 479 }
480 // Context save
Michael Starzinger 2013/09/12 18:38:51 nit: s/Context save/Save calling context./
481 __ movq(args.GetArgumentOperand(api_call_argc - 3), rsi);
483 __ movq(kScratchRegister, 482 __ movq(kScratchRegister,
484 ExternalReference::isolate_address(masm->isolate())); 483 ExternalReference::isolate_address(masm->isolate()));
485 __ movq(args.GetArgumentOperand(api_call_argc - 3), kScratchRegister); 484 __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
486 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 485 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
487 __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
488 __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister); 486 __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister);
487 __ movq(args.GetArgumentOperand(api_call_argc - 6), kScratchRegister);
489 488
490 // Prepare arguments. 489 // Prepare arguments.
491 STATIC_ASSERT(kFastApiCallArguments == 6); 490 STATIC_ASSERT(kFastApiCallArguments == 7);
492 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); 491 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize));
493 492
494 // Function address is a foreign pointer outside V8's heap. 493 // Function address is a foreign pointer outside V8's heap.
495 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 494 Address function_address = v8::ToCData<Address>(api_call_info->callback());
496 495
497 #if defined(__MINGW64__) || defined(_WIN64)
498 Register arguments_arg = rcx;
499 Register callback_arg = rdx;
500 #else
501 Register arguments_arg = rdi;
502 Register callback_arg = rsi;
503 #endif
504
505 // Allocate the v8::Arguments structure in the arguments' space since 496 // Allocate the v8::Arguments structure in the arguments' space since
506 // it's not controlled by GC. 497 // it's not controlled by GC.
507 const int kApiStackSpace = 4; 498 const int kApiStackSpace = 4;
508 499
500 // Get the function and setup the context.
501 Handle<JSFunction> function = optimization.constant_function();
502 __ LoadHeapObject(rdi, function);
503 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
504
509 __ PrepareCallApiFunction(kApiStackSpace); 505 __ PrepareCallApiFunction(kApiStackSpace);
510 506
511 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_. 507 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_.
512 __ addq(rbx, Immediate(argc * kPointerSize)); 508 __ addq(rbx, Immediate(argc * kPointerSize));
513 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_. 509 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_.
514 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_. 510 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_.
515 // v8::Arguments::is_construct_call_. 511 // v8::Arguments::is_construct_call_.
516 __ Set(StackSpaceOperand(3), 0); 512 __ Set(StackSpaceOperand(3), 0);
517 513
514 #if defined(__MINGW64__) || defined(_WIN64)
515 Register arguments_arg = rcx;
516 Register callback_arg = rdx;
517 #else
518 Register arguments_arg = rdi;
519 Register callback_arg = rsi;
520 #endif
521
518 // v8::InvocationCallback's argument. 522 // v8::InvocationCallback's argument.
519 __ lea(arguments_arg, StackSpaceOperand(0)); 523 __ lea(arguments_arg, StackSpaceOperand(0));
520 524
521 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 525 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
522 526
527 int context_restore_slot = restore_context ? kFastApiCallArguments - 2 : 0;
523 __ CallApiFunctionAndReturn(function_address, 528 __ CallApiFunctionAndReturn(function_address,
524 thunk_address, 529 thunk_address,
525 callback_arg, 530 callback_arg,
526 api_call_argc + 1, 531 api_call_argc + 1,
527 kFastApiCallArguments + 1); 532 kFastApiCallArguments + 1,
533 context_restore_slot);
528 } 534 }
529 535
530 536
531 // Generate call to api function. 537 // Generate call to api function.
532 static void GenerateFastApiCall(MacroAssembler* masm, 538 static void GenerateFastApiCall(MacroAssembler* masm,
533 const CallOptimization& optimization, 539 const CallOptimization& optimization,
534 Register receiver, 540 Register receiver,
535 Register scratch, 541 Register scratch,
536 int argc, 542 int argc,
537 Register* values) { 543 Register* values) {
(...skipping 12 matching lines...) Expand all
550 // Write receiver to stack frame. 556 // Write receiver to stack frame.
551 int index = stack_space; 557 int index = stack_space;
552 __ movq(Operand(rsp, index-- * kPointerSize), receiver); 558 __ movq(Operand(rsp, index-- * kPointerSize), receiver);
553 // Write the arguments to stack frame. 559 // Write the arguments to stack frame.
554 for (int i = 0; i < argc; i++) { 560 for (int i = 0; i < argc; i++) {
555 ASSERT(!receiver.is(values[i])); 561 ASSERT(!receiver.is(values[i]));
556 ASSERT(!scratch.is(values[i])); 562 ASSERT(!scratch.is(values[i]));
557 __ movq(Operand(rsp, index-- * kPointerSize), values[i]); 563 __ movq(Operand(rsp, index-- * kPointerSize), values[i]);
558 } 564 }
559 565
560 GenerateFastApiCall(masm, optimization, argc); 566 GenerateFastApiCall(masm, optimization, argc, true);
561 } 567 }
562 568
563 569
564 class CallInterceptorCompiler BASE_EMBEDDED { 570 class CallInterceptorCompiler BASE_EMBEDDED {
565 public: 571 public:
566 CallInterceptorCompiler(StubCompiler* stub_compiler, 572 CallInterceptorCompiler(StubCompiler* stub_compiler,
567 const ParameterCount& arguments, 573 const ParameterCount& arguments,
568 Register name, 574 Register name,
569 Code::ExtraICState extra_ic_state) 575 Code::ExtraICState extra_ic_state)
570 : stub_compiler_(stub_compiler), 576 : stub_compiler_(stub_compiler),
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 } else { 670 } else {
665 // CheckPrototypes has a side effect of fetching a 'holder' 671 // CheckPrototypes has a side effect of fetching a 'holder'
666 // for API (object which is instanceof for the signature). It's 672 // for API (object which is instanceof for the signature). It's
667 // safe to omit it here, as if present, it should be fetched 673 // safe to omit it here, as if present, it should be fetched
668 // by the previous CheckPrototypes. 674 // by the previous CheckPrototypes.
669 ASSERT(depth2 == kInvalidProtoDepth); 675 ASSERT(depth2 == kInvalidProtoDepth);
670 } 676 }
671 677
672 // Invoke function. 678 // Invoke function.
673 if (can_do_fast_api_call) { 679 if (can_do_fast_api_call) {
674 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 680 GenerateFastApiCall(masm, optimization, arguments_.immediate(), false);
675 } else { 681 } else {
676 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 682 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
677 ? CALL_AS_FUNCTION 683 ? CALL_AS_FUNCTION
678 : CALL_AS_METHOD; 684 : CALL_AS_METHOD;
679 Handle<JSFunction> fun = optimization.constant_function(); 685 Handle<JSFunction> fun = optimization.constant_function();
680 ParameterCount expected(fun); 686 ParameterCount expected(fun);
681 __ InvokeFunction(fun, expected, arguments_, 687 __ InvokeFunction(fun, expected, arguments_,
682 JUMP_FUNCTION, NullCallWrapper(), call_kind); 688 JUMP_FUNCTION, NullCallWrapper(), call_kind);
683 } 689 }
684 690
(...skipping 1811 matching lines...) Expand 10 before | Expand all | Expand 10 after
2496 2502
2497 // Check that the maps haven't changed and find a Holder as a side effect. 2503 // Check that the maps haven't changed and find a Holder as a side effect.
2498 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2504 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
2499 name, depth, &miss); 2505 name, depth, &miss);
2500 2506
2501 // Move the return address on top of the stack. 2507 // Move the return address on top of the stack.
2502 __ movq(rax, 2508 __ movq(rax,
2503 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); 2509 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize));
2504 __ movq(StackOperandForReturnAddress(0), rax); 2510 __ movq(StackOperandForReturnAddress(0), rax);
2505 2511
2506 GenerateFastApiCall(masm(), optimization, argc); 2512 GenerateFastApiCall(masm(), optimization, argc, false);
2507 2513
2508 __ bind(&miss); 2514 __ bind(&miss);
2509 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2515 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2510 2516
2511 __ bind(&miss_before_stack_reserved); 2517 __ bind(&miss_before_stack_reserved);
2512 GenerateMissBranch(); 2518 GenerateMissBranch();
2513 2519
2514 // Return the generated code. 2520 // Return the generated code.
2515 return GetCode(function); 2521 return GetCode(function);
2516 } 2522 }
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
3199 // ----------------------------------- 3205 // -----------------------------------
3200 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3206 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3201 } 3207 }
3202 3208
3203 3209
3204 #undef __ 3210 #undef __
3205 3211
3206 } } // namespace v8::internal 3212 } } // namespace v8::internal
3207 3213
3208 #endif // V8_TARGET_ARCH_X64 3214 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/x64/macro-assembler-x64.cc ('K') | « src/x64/macro-assembler-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698