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 24196002: revert 16744 for breaking build (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
« 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 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) {
448 // ----------- S t a t e ------------- 447 // ----------- S t a t e -------------
449 // -- rsp[0] : return address 448 // -- rsp[0] : return address
450 // -- rsp[8] : context save 449 // -- rsp[8] : object passing the type check
451 // -- rsp[16] : object passing the type check
452 // (last fast api call extra argument, 450 // (last fast api call extra argument,
453 // set by CheckPrototypes) 451 // set by CheckPrototypes)
454 // -- rsp[24] : api function 452 // -- rsp[16] : api function
455 // (first fast api call extra argument) 453 // (first fast api call extra argument)
456 // -- rsp[32] : api call data 454 // -- rsp[24] : api call data
457 // -- rsp[40] : isolate 455 // -- rsp[32] : isolate
458 // -- rsp[48] : ReturnValue default value 456 // -- rsp[40] : ReturnValue default value
459 // -- rsp[56] : ReturnValue 457 // -- rsp[48] : ReturnValue
460 // 458 //
461 // -- rsp[64] : last argument 459 // -- rsp[56] : last argument
462 // -- ... 460 // -- ...
463 // -- rsp[(argc + 7) * 8] : first argument 461 // -- rsp[(argc + 6) * 8] : first argument
464 // -- rsp[(argc + 8) * 8] : receiver 462 // -- rsp[(argc + 7) * 8] : receiver
465 // ----------------------------------- 463 // -----------------------------------
466 int api_call_argc = argc + kFastApiCallArguments;
467 StackArgumentsAccessor args(rsp, api_call_argc);
468
469 // Save calling context.
470 __ movq(args.GetArgumentOperand(api_call_argc), rsi);
471
472 // Get the function and setup the context. 464 // Get the function and setup the context.
473 Handle<JSFunction> function = optimization.constant_function(); 465 Handle<JSFunction> function = optimization.constant_function();
474 __ LoadHeapObject(rdi, function); 466 __ LoadHeapObject(rdi, function);
475 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 467 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
468
469 int api_call_argc = argc + kFastApiCallArguments;
470 StackArgumentsAccessor args(rsp, api_call_argc);
471
476 // Pass the additional arguments. 472 // Pass the additional arguments.
477 __ movq(args.GetArgumentOperand(api_call_argc - 2), rdi); 473 __ movq(args.GetArgumentOperand(api_call_argc - 1), rdi);
478 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 474 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
479 Handle<Object> call_data(api_call_info->data(), masm->isolate()); 475 Handle<Object> call_data(api_call_info->data(), masm->isolate());
480 if (masm->isolate()->heap()->InNewSpace(*call_data)) { 476 if (masm->isolate()->heap()->InNewSpace(*call_data)) {
481 __ Move(rcx, api_call_info); 477 __ Move(rcx, api_call_info);
482 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); 478 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
483 __ movq(args.GetArgumentOperand(api_call_argc - 3), rbx); 479 __ movq(args.GetArgumentOperand(api_call_argc - 2), rbx);
484 } else { 480 } else {
485 __ Move(args.GetArgumentOperand(api_call_argc - 3), call_data); 481 __ Move(args.GetArgumentOperand(api_call_argc - 2), call_data);
486 } 482 }
487 __ movq(kScratchRegister, 483 __ movq(kScratchRegister,
488 ExternalReference::isolate_address(masm->isolate())); 484 ExternalReference::isolate_address(masm->isolate()));
485 __ movq(args.GetArgumentOperand(api_call_argc - 3), kScratchRegister);
486 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
489 __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister); 487 __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
490 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
491 __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister); 488 __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister);
492 __ movq(args.GetArgumentOperand(api_call_argc - 6), kScratchRegister);
493 489
494 // Prepare arguments. 490 // Prepare arguments.
495 STATIC_ASSERT(kFastApiCallArguments == 7); 491 STATIC_ASSERT(kFastApiCallArguments == 6);
496 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); 492 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize));
497 493
498 // Function address is a foreign pointer outside V8's heap. 494 // Function address is a foreign pointer outside V8's heap.
499 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 495 Address function_address = v8::ToCData<Address>(api_call_info->callback());
500 496
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
501 // Allocate the v8::Arguments structure in the arguments' space since 505 // Allocate the v8::Arguments structure in the arguments' space since
502 // it's not controlled by GC. 506 // it's not controlled by GC.
503 const int kApiStackSpace = 4; 507 const int kApiStackSpace = 4;
504 508
505 __ PrepareCallApiFunction(kApiStackSpace); 509 __ PrepareCallApiFunction(kApiStackSpace);
506 510
507 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_. 511 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_.
508 __ addq(rbx, Immediate(argc * kPointerSize)); 512 __ addq(rbx, Immediate(argc * kPointerSize));
509 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_. 513 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_.
510 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_. 514 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_.
511 // v8::Arguments::is_construct_call_. 515 // v8::Arguments::is_construct_call_.
512 __ Set(StackSpaceOperand(3), 0); 516 __ Set(StackSpaceOperand(3), 0);
513 517
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
522 // v8::InvocationCallback's argument. 518 // v8::InvocationCallback's argument.
523 __ lea(arguments_arg, StackSpaceOperand(0)); 519 __ lea(arguments_arg, StackSpaceOperand(0));
524 520
525 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 521 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
526 522
527 Operand context_restore_operand(rbp, 2 * kPointerSize);
528 Operand return_value_operand(
529 rbp, (kFastApiCallArguments + 1) * kPointerSize);
530 __ CallApiFunctionAndReturn(function_address, 523 __ CallApiFunctionAndReturn(function_address,
531 thunk_address, 524 thunk_address,
532 callback_arg, 525 callback_arg,
533 api_call_argc + 1, 526 api_call_argc + 1,
534 return_value_operand, 527 kFastApiCallArguments + 1);
535 restore_context ?
536 &context_restore_operand : NULL);
537 } 528 }
538 529
539 530
540 // Generate call to api function. 531 // Generate call to api function.
541 static void GenerateFastApiCall(MacroAssembler* masm, 532 static void GenerateFastApiCall(MacroAssembler* masm,
542 const CallOptimization& optimization, 533 const CallOptimization& optimization,
543 Register receiver, 534 Register receiver,
544 Register scratch, 535 Register scratch,
545 int argc, 536 int argc,
546 Register* values) { 537 Register* values) {
547 ASSERT(optimization.is_simple_api_call()); 538 ASSERT(optimization.is_simple_api_call());
548 ASSERT(!receiver.is(scratch)); 539 ASSERT(!receiver.is(scratch));
549 540
550 const int stack_space = kFastApiCallArguments + argc + 1; 541 const int stack_space = kFastApiCallArguments + argc + 1;
551 const int kHolderIndex = kFastApiCallArguments +
552 FunctionCallbackArguments::kHolderIndex;
553 // Copy return value. 542 // Copy return value.
554 __ movq(scratch, Operand(rsp, 0)); 543 __ movq(scratch, Operand(rsp, 0));
555 // Assign stack space for the call arguments. 544 // Assign stack space for the call arguments.
556 __ subq(rsp, Immediate(stack_space * kPointerSize)); 545 __ subq(rsp, Immediate(stack_space * kPointerSize));
557 // Move the return address on top of the stack. 546 // Move the return address on top of the stack.
558 __ movq(Operand(rsp, 0), scratch); 547 __ movq(Operand(rsp, 0), scratch);
559 // Write holder to stack frame. 548 // Write holder to stack frame.
560 __ movq(Operand(rsp, kHolderIndex * kPointerSize), receiver); 549 __ movq(Operand(rsp, 1 * kPointerSize), receiver);
561 // Write receiver to stack frame. 550 // Write receiver to stack frame.
562 int index = stack_space; 551 int index = stack_space;
563 __ movq(Operand(rsp, index-- * kPointerSize), receiver); 552 __ movq(Operand(rsp, index-- * kPointerSize), receiver);
564 // Write the arguments to stack frame. 553 // Write the arguments to stack frame.
565 for (int i = 0; i < argc; i++) { 554 for (int i = 0; i < argc; i++) {
566 ASSERT(!receiver.is(values[i])); 555 ASSERT(!receiver.is(values[i]));
567 ASSERT(!scratch.is(values[i])); 556 ASSERT(!scratch.is(values[i]));
568 __ movq(Operand(rsp, index-- * kPointerSize), values[i]); 557 __ movq(Operand(rsp, index-- * kPointerSize), values[i]);
569 } 558 }
570 559
571 GenerateFastApiCall(masm, optimization, argc, true); 560 GenerateFastApiCall(masm, optimization, argc);
572 } 561 }
573 562
574 563
575 class CallInterceptorCompiler BASE_EMBEDDED { 564 class CallInterceptorCompiler BASE_EMBEDDED {
576 public: 565 public:
577 CallInterceptorCompiler(StubCompiler* stub_compiler, 566 CallInterceptorCompiler(StubCompiler* stub_compiler,
578 const ParameterCount& arguments, 567 const ParameterCount& arguments,
579 Register name, 568 Register name,
580 Code::ExtraICState extra_ic_state) 569 Code::ExtraICState extra_ic_state)
581 : stub_compiler_(stub_compiler), 570 : stub_compiler_(stub_compiler),
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 } else { 664 } else {
676 // CheckPrototypes has a side effect of fetching a 'holder' 665 // CheckPrototypes has a side effect of fetching a 'holder'
677 // for API (object which is instanceof for the signature). It's 666 // for API (object which is instanceof for the signature). It's
678 // safe to omit it here, as if present, it should be fetched 667 // safe to omit it here, as if present, it should be fetched
679 // by the previous CheckPrototypes. 668 // by the previous CheckPrototypes.
680 ASSERT(depth2 == kInvalidProtoDepth); 669 ASSERT(depth2 == kInvalidProtoDepth);
681 } 670 }
682 671
683 // Invoke function. 672 // Invoke function.
684 if (can_do_fast_api_call) { 673 if (can_do_fast_api_call) {
685 GenerateFastApiCall(masm, optimization, arguments_.immediate(), false); 674 GenerateFastApiCall(masm, optimization, arguments_.immediate());
686 } else { 675 } else {
687 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 676 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
688 ? CALL_AS_FUNCTION 677 ? CALL_AS_FUNCTION
689 : CALL_AS_METHOD; 678 : CALL_AS_METHOD;
690 Handle<JSFunction> fun = optimization.constant_function(); 679 Handle<JSFunction> fun = optimization.constant_function();
691 ParameterCount expected(fun); 680 ParameterCount expected(fun);
692 __ InvokeFunction(fun, expected, arguments_, 681 __ InvokeFunction(fun, expected, arguments_,
693 JUMP_FUNCTION, NullCallWrapper(), call_kind); 682 JUMP_FUNCTION, NullCallWrapper(), call_kind);
694 } 683 }
695 684
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1080 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
1092 Register object_reg, 1081 Register object_reg,
1093 Handle<JSObject> holder, 1082 Handle<JSObject> holder,
1094 Register holder_reg, 1083 Register holder_reg,
1095 Register scratch1, 1084 Register scratch1,
1096 Register scratch2, 1085 Register scratch2,
1097 Handle<Name> name, 1086 Handle<Name> name,
1098 int save_at_depth, 1087 int save_at_depth,
1099 Label* miss, 1088 Label* miss,
1100 PrototypeCheckType check) { 1089 PrototypeCheckType check) {
1101 const int kHolderIndex = kFastApiCallArguments +
1102 FunctionCallbackArguments::kHolderIndex;
1103 // Make sure that the type feedback oracle harvests the receiver map. 1090 // Make sure that the type feedback oracle harvests the receiver map.
1104 // TODO(svenpanne) Remove this hack when all ICs are reworked. 1091 // TODO(svenpanne) Remove this hack when all ICs are reworked.
1105 __ Move(scratch1, Handle<Map>(object->map())); 1092 __ Move(scratch1, Handle<Map>(object->map()));
1106 1093
1107 Handle<JSObject> first = object; 1094 Handle<JSObject> first = object;
1108 // Make sure there's no overlap between holder and object registers. 1095 // Make sure there's no overlap between holder and object registers.
1109 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1096 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1110 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1097 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1111 && !scratch2.is(scratch1)); 1098 && !scratch2.is(scratch1));
1112 1099
1113 // Keep track of the current object in register reg. On the first 1100 // Keep track of the current object in register reg. On the first
1114 // iteration, reg is an alias for object_reg, on later iterations, 1101 // iteration, reg is an alias for object_reg, on later iterations,
1115 // it is an alias for holder_reg. 1102 // it is an alias for holder_reg.
1116 Register reg = object_reg; 1103 Register reg = object_reg;
1117 int depth = 0; 1104 int depth = 0;
1118 1105
1119 if (save_at_depth == depth) { 1106 if (save_at_depth == depth) {
1120 __ movq(Operand(rsp, kHolderIndex * kPointerSize), object_reg); 1107 __ movq(Operand(rsp, kPCOnStackSize), object_reg);
1121 } 1108 }
1122 1109
1123 // Check the maps in the prototype chain. 1110 // Check the maps in the prototype chain.
1124 // Traverse the prototype chain from the object and do map checks. 1111 // Traverse the prototype chain from the object and do map checks.
1125 Handle<JSObject> current = object; 1112 Handle<JSObject> current = object;
1126 while (!current.is_identical_to(holder)) { 1113 while (!current.is_identical_to(holder)) {
1127 ++depth; 1114 ++depth;
1128 1115
1129 // Only global objects and objects that do not require access 1116 // Only global objects and objects that do not require access
1130 // checks are allowed in stubs. 1117 // checks are allowed in stubs.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 // The prototype is in new space; we cannot store a reference to it 1157 // The prototype is in new space; we cannot store a reference to it
1171 // in the code. Load it from the map. 1158 // in the code. Load it from the map.
1172 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1159 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1173 } else { 1160 } else {
1174 // The prototype is in old space; load it directly. 1161 // The prototype is in old space; load it directly.
1175 __ Move(reg, prototype); 1162 __ Move(reg, prototype);
1176 } 1163 }
1177 } 1164 }
1178 1165
1179 if (save_at_depth == depth) { 1166 if (save_at_depth == depth) {
1180 __ movq(Operand(rsp, kHolderIndex * kPointerSize), reg); 1167 __ movq(Operand(rsp, kPCOnStackSize), reg);
1181 } 1168 }
1182 1169
1183 // Go to the next object in the prototype chain. 1170 // Go to the next object in the prototype chain.
1184 current = prototype; 1171 current = prototype;
1185 } 1172 }
1186 ASSERT(current.is_identical_to(holder)); 1173 ASSERT(current.is_identical_to(holder));
1187 1174
1188 // Log the check depth. 1175 // Log the check depth.
1189 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1176 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1190 1177
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 // The context register (rsi) has been saved in PrepareCallApiFunction and 1379 // The context register (rsi) has been saved in PrepareCallApiFunction and
1393 // could be used to pass arguments. 1380 // could be used to pass arguments.
1394 __ lea(accessor_info_arg, StackSpaceOperand(0)); 1381 __ lea(accessor_info_arg, StackSpaceOperand(0));
1395 1382
1396 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); 1383 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
1397 1384
1398 __ CallApiFunctionAndReturn(getter_address, 1385 __ CallApiFunctionAndReturn(getter_address,
1399 thunk_address, 1386 thunk_address,
1400 getter_arg, 1387 getter_arg,
1401 kStackSpace, 1388 kStackSpace,
1402 Operand(rbp, 6 * kPointerSize), 1389 6);
1403 NULL);
1404 } 1390 }
1405 1391
1406 1392
1407 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1393 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1408 // Return the constant value. 1394 // Return the constant value.
1409 __ LoadObject(rax, value); 1395 __ LoadObject(rax, value);
1410 __ ret(0); 1396 __ ret(0);
1411 } 1397 }
1412 1398
1413 1399
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
2511 2497
2512 // Check that the maps haven't changed and find a Holder as a side effect. 2498 // Check that the maps haven't changed and find a Holder as a side effect.
2513 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2499 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
2514 name, depth, &miss); 2500 name, depth, &miss);
2515 2501
2516 // Move the return address on top of the stack. 2502 // Move the return address on top of the stack.
2517 __ movq(rax, 2503 __ movq(rax,
2518 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); 2504 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize));
2519 __ movq(StackOperandForReturnAddress(0), rax); 2505 __ movq(StackOperandForReturnAddress(0), rax);
2520 2506
2521 GenerateFastApiCall(masm(), optimization, argc, false); 2507 GenerateFastApiCall(masm(), optimization, argc);
2522 2508
2523 __ bind(&miss); 2509 __ bind(&miss);
2524 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2510 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2525 2511
2526 __ bind(&miss_before_stack_reserved); 2512 __ bind(&miss_before_stack_reserved);
2527 GenerateMissBranch(); 2513 GenerateMissBranch();
2528 2514
2529 // Return the generated code. 2515 // Return the generated code.
2530 return GetCode(function); 2516 return GetCode(function);
2531 } 2517 }
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
3172 // ----------------------------------- 3158 // -----------------------------------
3173 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3159 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3174 } 3160 }
3175 3161
3176 3162
3177 #undef __ 3163 #undef __
3178 3164
3179 } } // namespace v8::internal 3165 } } // namespace v8::internal
3180 3166
3181 #endif // V8_TARGET_ARCH_X64 3167 #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