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

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

Issue 140613004: stub fast api calls (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: comments Created 6 years, 10 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
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 Register name, 381 Register name,
382 Handle<JSObject> holder_obj, 382 Handle<JSObject> holder_obj,
383 IC::UtilityId id) { 383 IC::UtilityId id) {
384 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 384 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
385 __ CallExternalReference( 385 __ CallExternalReference(
386 ExternalReference(IC_Utility(id), masm->isolate()), 386 ExternalReference(IC_Utility(id), masm->isolate()),
387 StubCache::kInterceptorArgsLength); 387 StubCache::kInterceptorArgsLength);
388 } 388 }
389 389
390 390
391 // Number of pointers to be reserved on stack for fast API call.
392 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength;
393
394
395 static void GenerateFastApiCallBody(MacroAssembler* masm, 391 static void GenerateFastApiCallBody(MacroAssembler* masm,
396 const CallOptimization& optimization, 392 const CallOptimization& optimization,
397 int argc, 393 int argc,
398 Register holder, 394 Register holder_in,
399 Register scratch1, 395 bool restore_context) {
400 Register scratch2, 396 ASSERT(optimization.is_simple_api_call());
401 Register scratch3, 397
402 bool restore_context); 398 // Abi for CallApiFunctionStub.
399 Register callee = rax;
400 Register call_data = rbx;
401 Register holder = rcx;
402 Register api_function_address = rdx;
403
404 // Put holder in place.
405 __ Move(holder, holder_in);
406
407 Register scratch = rdi;
408
409 Isolate* isolate = masm->isolate();
410 Handle<JSFunction> function = optimization.constant_function();
411 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
412 Handle<Object> call_data_obj(api_call_info->data(), isolate);
413
414 // Put callee in place.
415 __ Move(callee, function);
416
417 bool call_data_undefined = false;
418 // Put call_data in place.
419 if (isolate->heap()->InNewSpace(*call_data_obj)) {
420 __ Move(scratch, api_call_info);
421 __ movp(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset));
422 } else if (call_data_obj->IsUndefined()) {
423 call_data_undefined = true;
424 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
425 } else {
426 __ Move(call_data, call_data_obj);
427 }
428
429 // Put api_function_address in place.
430 Address function_address = v8::ToCData<Address>(api_call_info->callback());
431 __ Move(
432 api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE);
433
434 // Jump to stub.
435 CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
436 __ TailCallStub(&stub);
437 }
403 438
404 439
405 // Generates call to API function. 440 // Generates call to API function.
406 static void GenerateFastApiCall(MacroAssembler* masm, 441 static void GenerateFastApiCall(MacroAssembler* masm,
407 const CallOptimization& optimization, 442 const CallOptimization& optimization,
408 int argc, 443 int argc,
409 Handle<Map> map_to_holder, 444 Handle<Map> map_to_holder,
410 CallOptimization::HolderLookup holder_lookup) { 445 CallOptimization::HolderLookup holder_lookup) {
411 Counters* counters = masm->isolate()->counters(); 446 Counters* counters = masm->isolate()->counters();
412 __ IncrementCounter(counters->call_const_fast_api(), 1); 447 __ IncrementCounter(counters->call_const_fast_api(), 1);
(...skipping 19 matching lines...) Expand all
432 } 467 }
433 } 468 }
434 break; 469 break;
435 case CallOptimization::kHolderNotFound: 470 case CallOptimization::kHolderNotFound:
436 UNREACHABLE(); 471 UNREACHABLE();
437 } 472 }
438 GenerateFastApiCallBody(masm, 473 GenerateFastApiCallBody(masm,
439 optimization, 474 optimization,
440 argc, 475 argc,
441 holder_reg, 476 holder_reg,
442 rbx,
443 rcx,
444 rdx,
445 false); 477 false);
446 } 478 }
447 479
448 480
449 // Generate call to api function. 481 // Generate call to api function.
450 // This function uses push() to generate smaller, faster code than
451 // the version above. It is an optimization that should will be removed
452 // when api call ICs are generated in hydrogen.
453 static void GenerateFastApiCall(MacroAssembler* masm, 482 static void GenerateFastApiCall(MacroAssembler* masm,
454 const CallOptimization& optimization, 483 const CallOptimization& optimization,
455 Register receiver, 484 Register receiver,
456 Register scratch1, 485 Register scratch1,
457 Register scratch2,
458 Register scratch3,
459 int argc, 486 int argc,
460 Register* values) { 487 Register* values) {
461 __ PopReturnAddressTo(scratch1); 488 __ PopReturnAddressTo(scratch1);
462 // receiver 489 // receiver
463 __ push(receiver); 490 __ push(receiver);
464 // Write the arguments to stack frame. 491 // Write the arguments to stack frame.
465 for (int i = 0; i < argc; i++) { 492 for (int i = 0; i < argc; i++) {
466 Register arg = values[argc-1-i]; 493 Register arg = values[argc-1-i];
467 ASSERT(!receiver.is(arg)); 494 ASSERT(!receiver.is(arg));
468 ASSERT(!scratch1.is(arg)); 495 ASSERT(!scratch1.is(arg));
469 ASSERT(!scratch2.is(arg));
470 ASSERT(!scratch3.is(arg));
471 __ push(arg); 496 __ push(arg);
472 } 497 }
473 __ PushReturnAddressFrom(scratch1); 498 __ PushReturnAddressFrom(scratch1);
474 // Stack now matches JSFunction abi. 499 // Stack now matches JSFunction abi.
475 GenerateFastApiCallBody(masm, 500 GenerateFastApiCallBody(masm,
476 optimization, 501 optimization,
477 argc, 502 argc,
478 receiver, 503 receiver,
479 scratch1,
480 scratch2,
481 scratch3,
482 true); 504 true);
483 } 505 }
484 506
485 507
486 static void GenerateFastApiCallBody(MacroAssembler* masm,
487 const CallOptimization& optimization,
488 int argc,
489 Register holder,
490 Register scratch1,
491 Register scratch2,
492 Register scratch3,
493 bool restore_context) {
494 // ----------- S t a t e -------------
495 // -- rsp[0] : return address
496 // -- rsp[8] : last argument
497 // -- ...
498 // -- rsp[argc * 8] : first argument
499 // -- rsp[(argc + 1) * 8] : receiver
500 // -----------------------------------
501 ASSERT(optimization.is_simple_api_call());
502
503 typedef FunctionCallbackArguments FCA;
504
505 STATIC_ASSERT(FCA::kHolderIndex == 0);
506 STATIC_ASSERT(FCA::kIsolateIndex == 1);
507 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
508 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
509 STATIC_ASSERT(FCA::kDataIndex == 4);
510 STATIC_ASSERT(FCA::kCalleeIndex == 5);
511 STATIC_ASSERT(FCA::kContextSaveIndex == 6);
512 STATIC_ASSERT(FCA::kArgsLength == 7);
513
514 __ PopReturnAddressTo(scratch1);
515
516 ASSERT(!holder.is(rsi));
517 // context save
518 __ push(rsi);
519
520 // Get the function and setup the context.
521 Handle<JSFunction> function = optimization.constant_function();
522 __ Move(scratch2, function);
523 __ push(scratch2);
524 __ movp(rsi, FieldOperand(scratch2, JSFunction::kContextOffset));
525
526 Isolate* isolate = masm->isolate();
527 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
528 Handle<Object> call_data(api_call_info->data(), isolate);
529 // Push data from ExecutableAccessorInfo.
530 bool call_data_undefined = false;
531 if (isolate->heap()->InNewSpace(*call_data)) {
532 __ Move(scratch2, api_call_info);
533 __ movp(scratch3, FieldOperand(scratch2, CallHandlerInfo::kDataOffset));
534 } else if (call_data->IsUndefined()) {
535 call_data_undefined = true;
536 __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex);
537 } else {
538 __ Move(scratch3, call_data);
539 }
540 // call data
541 __ push(scratch3);
542 if (!call_data_undefined) {
543 __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex);
544 }
545 // return value
546 __ push(scratch3);
547 // return value default
548 __ push(scratch3);
549 // isolate
550 __ Move(scratch3,
551 ExternalReference::isolate_address(masm->isolate()));
552 __ push(scratch3);
553 // holder
554 __ push(holder);
555
556 ASSERT(!scratch1.is(rax));
557 __ movp(rax, rsp);
558 // Push return address back on stack.
559 __ PushReturnAddressFrom(scratch1);
560
561 // Function address is a foreign pointer outside V8's heap.
562 Address function_address = v8::ToCData<Address>(api_call_info->callback());
563
564 // Allocate the v8::Arguments structure in the arguments' space since
565 // it's not controlled by GC.
566 const int kApiStackSpace = 4;
567
568 __ PrepareCallApiFunction(kApiStackSpace);
569
570 __ movp(StackSpaceOperand(0), rax); // FunctionCallbackInfo::implicit_args_.
571 __ addq(rax, Immediate((argc + kFastApiCallArguments - 1) * kPointerSize));
572 __ movp(StackSpaceOperand(1), rax); // FunctionCallbackInfo::values_.
573 __ Set(StackSpaceOperand(2), argc); // FunctionCallbackInfo::length_.
574 // FunctionCallbackInfo::is_construct_call_.
575 __ Set(StackSpaceOperand(3), 0);
576
577 #if defined(__MINGW64__) || defined(_WIN64)
578 Register arguments_arg = rcx;
579 Register callback_arg = rdx;
580 #else
581 Register arguments_arg = rdi;
582 Register callback_arg = rsi;
583 #endif
584
585 // v8::InvocationCallback's argument.
586 __ lea(arguments_arg, StackSpaceOperand(0));
587
588 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
589
590 StackArgumentsAccessor args_from_rbp(rbp, kFastApiCallArguments,
591 ARGUMENTS_DONT_CONTAIN_RECEIVER);
592 Operand context_restore_operand = args_from_rbp.GetArgumentOperand(
593 kFastApiCallArguments - 1 - FCA::kContextSaveIndex);
594 Operand return_value_operand = args_from_rbp.GetArgumentOperand(
595 kFastApiCallArguments - 1 - FCA::kReturnValueOffset);
596 __ CallApiFunctionAndReturn(
597 function_address,
598 thunk_address,
599 callback_arg,
600 argc + kFastApiCallArguments + 1,
601 return_value_operand,
602 restore_context ? &context_restore_operand : NULL);
603 }
604
605
606 class CallInterceptorCompiler BASE_EMBEDDED { 508 class CallInterceptorCompiler BASE_EMBEDDED {
607 public: 509 public:
608 CallInterceptorCompiler(CallStubCompiler* stub_compiler, 510 CallInterceptorCompiler(CallStubCompiler* stub_compiler,
609 const ParameterCount& arguments, 511 const ParameterCount& arguments,
610 Register name) 512 Register name)
611 : stub_compiler_(stub_compiler), 513 : stub_compiler_(stub_compiler),
612 arguments_(arguments), 514 arguments_(arguments),
613 name_(name) {} 515 name_(name) {}
614 516
615 void Compile(MacroAssembler* masm, 517 void Compile(MacroAssembler* masm,
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 representation); 1174 representation);
1273 GenerateTailCall(masm(), stub.GetCode(isolate())); 1175 GenerateTailCall(masm(), stub.GetCode(isolate()));
1274 } 1176 }
1275 } 1177 }
1276 1178
1277 1179
1278 void LoadStubCompiler::GenerateLoadCallback( 1180 void LoadStubCompiler::GenerateLoadCallback(
1279 const CallOptimization& call_optimization) { 1181 const CallOptimization& call_optimization) {
1280 GenerateFastApiCall( 1182 GenerateFastApiCall(
1281 masm(), call_optimization, receiver(), 1183 masm(), call_optimization, receiver(),
1282 scratch1(), scratch2(), name(), 0, NULL); 1184 scratch1(), 0, NULL);
1283 } 1185 }
1284 1186
1285 1187
1286 void LoadStubCompiler::GenerateLoadCallback( 1188 void LoadStubCompiler::GenerateLoadCallback(
1287 Register reg, 1189 Register reg,
1288 Handle<ExecutableAccessorInfo> callback) { 1190 Handle<ExecutableAccessorInfo> callback) {
1289 // Insert additional parameters into the stack frame above return address. 1191 // Insert additional parameters into the stack frame above return address.
1290 ASSERT(!scratch4().is(reg)); 1192 ASSERT(!scratch4().is(reg));
1291 __ PopReturnAddressTo(scratch4()); 1193 __ PopReturnAddressTo(scratch4());
1292 1194
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 1245
1344 // v8::PropertyAccessorInfo::args_. 1246 // v8::PropertyAccessorInfo::args_.
1345 __ movp(StackSpaceOperand(0), rax); 1247 __ movp(StackSpaceOperand(0), rax);
1346 1248
1347 // The context register (rsi) has been saved in PrepareCallApiFunction and 1249 // The context register (rsi) has been saved in PrepareCallApiFunction and
1348 // could be used to pass arguments. 1250 // could be used to pass arguments.
1349 __ lea(accessor_info_arg, StackSpaceOperand(0)); 1251 __ lea(accessor_info_arg, StackSpaceOperand(0));
1350 1252
1351 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); 1253 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
1352 1254
1255 Register api_function_address = rdx;
1256 __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE);
1257
1353 // The name handler is counted as an argument. 1258 // The name handler is counted as an argument.
1354 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength); 1259 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength);
1355 Operand return_value_operand = args.GetArgumentOperand( 1260 Operand return_value_operand = args.GetArgumentOperand(
1356 PropertyCallbackArguments::kArgsLength - 1 - 1261 PropertyCallbackArguments::kArgsLength - 1 -
1357 PropertyCallbackArguments::kReturnValueOffset); 1262 PropertyCallbackArguments::kReturnValueOffset);
1358 __ CallApiFunctionAndReturn(getter_address, 1263 __ CallApiFunctionAndReturn(api_function_address,
1359 thunk_address, 1264 thunk_address,
1360 getter_arg, 1265 getter_arg,
1361 kStackSpace, 1266 kStackSpace,
1362 return_value_operand, 1267 return_value_operand,
1363 NULL); 1268 NULL);
1364 } 1269 }
1365 1270
1366 1271
1367 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1272 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1368 // Return the constant value. 1273 // Return the constant value.
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
1785 Handle<Code> StoreStubCompiler::CompileStoreCallback( 1690 Handle<Code> StoreStubCompiler::CompileStoreCallback(
1786 Handle<JSObject> object, 1691 Handle<JSObject> object,
1787 Handle<JSObject> holder, 1692 Handle<JSObject> holder,
1788 Handle<Name> name, 1693 Handle<Name> name,
1789 const CallOptimization& call_optimization) { 1694 const CallOptimization& call_optimization) {
1790 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), 1695 HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
1791 receiver(), holder, name); 1696 receiver(), holder, name);
1792 1697
1793 Register values[] = { value() }; 1698 Register values[] = { value() };
1794 GenerateFastApiCall( 1699 GenerateFastApiCall(
1795 masm(), call_optimization, receiver(), scratch1(), 1700 masm(), call_optimization, receiver(),
1796 scratch2(), this->name(), 1, values); 1701 scratch1(), 1, values);
1797 1702
1798 // Return the generated code. 1703 // Return the generated code.
1799 return GetCode(kind(), Code::FAST, name); 1704 return GetCode(kind(), Code::FAST, name);
1800 } 1705 }
1801 1706
1802 1707
1803 #undef __ 1708 #undef __
1804 #define __ ACCESS_MASM(masm) 1709 #define __ ACCESS_MASM(masm)
1805 1710
1806 1711
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
2112 // ----------------------------------- 2017 // -----------------------------------
2113 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2018 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2114 } 2019 }
2115 2020
2116 2021
2117 #undef __ 2022 #undef __
2118 2023
2119 } } // namespace v8::internal 2024 } } // namespace v8::internal
2120 2025
2121 #endif // V8_TARGET_ARCH_X64 2026 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698