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

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

Issue 145773008: A64: Synchronize with r17104. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: 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') | test/cctest/cctest.status » ('j') | 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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 bool restore_context) {
448 // ----------- S t a t e ------------- 448 // ----------- S t a t e -------------
449 // -- rsp[0] : return address 449 // -- rsp[0] : return address
450 // -- rsp[8] - rsp[58] : FunctionCallbackInfo, incl. 450 // -- rsp[8] - rsp[56] : FunctionCallbackInfo, incl.
451 // : object passing the type check 451 // : object passing the type check
452 // (set by CheckPrototypes) 452 // (set by CheckPrototypes)
453 // -- rsp[64] : last argument 453 // -- rsp[64] : last argument
454 // -- ... 454 // -- ...
455 // -- rsp[(argc + 7) * 8] : first argument 455 // -- rsp[(argc + 7) * 8] : first argument
456 // -- rsp[(argc + 8) * 8] : receiver 456 // -- rsp[(argc + 8) * 8] : receiver
457 // ----------------------------------- 457 // -----------------------------------
458 typedef FunctionCallbackArguments FCA; 458 typedef FunctionCallbackArguments FCA;
459 StackArgumentsAccessor args(rsp, argc + kFastApiCallArguments); 459 StackArgumentsAccessor args(rsp, argc + kFastApiCallArguments);
460 460
461 // Save calling context. 461 // Save calling context.
462 __ movq(args.GetArgumentOperand(argc + 1 - FCA::kContextSaveIndex), rsi); 462 int offset = argc + kFastApiCallArguments;
463 __ movq(args.GetArgumentOperand(offset - FCA::kContextSaveIndex), rsi);
463 464
464 // Get the function and setup the context. 465 // Get the function and setup the context.
465 Handle<JSFunction> function = optimization.constant_function(); 466 Handle<JSFunction> function = optimization.constant_function();
466 __ LoadHeapObject(rdi, function); 467 __ LoadHeapObject(rdi, function);
467 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 468 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
468 // Construct the FunctionCallbackInfo on the stack. 469 // Construct the FunctionCallbackInfo on the stack.
469 __ movq(args.GetArgumentOperand(argc + 1 - FCA::kCalleeIndex), rdi); 470 __ movq(args.GetArgumentOperand(offset - FCA::kCalleeIndex), rdi);
470 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 471 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
471 Handle<Object> call_data(api_call_info->data(), masm->isolate()); 472 Handle<Object> call_data(api_call_info->data(), masm->isolate());
472 if (masm->isolate()->heap()->InNewSpace(*call_data)) { 473 if (masm->isolate()->heap()->InNewSpace(*call_data)) {
473 __ Move(rcx, api_call_info); 474 __ Move(rcx, api_call_info);
474 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); 475 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
475 __ movq(args.GetArgumentOperand(argc + 1 - FCA::kDataIndex), rbx); 476 __ movq(args.GetArgumentOperand(offset - FCA::kDataIndex), rbx);
476 } else { 477 } else {
477 __ Move(args.GetArgumentOperand(argc + 1 - FCA::kDataIndex), call_data); 478 __ Move(args.GetArgumentOperand(offset - FCA::kDataIndex), call_data);
478 } 479 }
479 __ movq(kScratchRegister, 480 __ movq(kScratchRegister,
480 ExternalReference::isolate_address(masm->isolate())); 481 ExternalReference::isolate_address(masm->isolate()));
481 __ movq(args.GetArgumentOperand(argc + 1 - FCA::kIsolateIndex), 482 __ movq(args.GetArgumentOperand(offset - FCA::kIsolateIndex),
482 kScratchRegister); 483 kScratchRegister);
483 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 484 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
484 __ movq( 485 __ movq(args.GetArgumentOperand(offset - FCA::kReturnValueDefaultValueIndex),
485 args.GetArgumentOperand(argc + 1 - FCA::kReturnValueDefaultValueIndex), 486 kScratchRegister);
486 kScratchRegister); 487 __ movq(args.GetArgumentOperand(offset - FCA::kReturnValueOffset),
487 __ movq(args.GetArgumentOperand(argc + 1 - FCA::kReturnValueOffset),
488 kScratchRegister); 488 kScratchRegister);
489 489
490 // Prepare arguments. 490 // Prepare arguments.
491 STATIC_ASSERT(kFastApiCallArguments == 7); 491 STATIC_ASSERT(kFastApiCallArguments == 7);
492 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); 492 __ lea(rbx, Operand(rsp, 1 * kPointerSize));
493 493
494 // Function address is a foreign pointer outside V8's heap. 494 // Function address is a foreign pointer outside V8's heap.
495 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 495 Address function_address = v8::ToCData<Address>(api_call_info->callback());
496 496
497 // Allocate the v8::Arguments structure in the arguments' space since 497 // Allocate the v8::Arguments structure in the arguments' space since
498 // it's not controlled by GC. 498 // it's not controlled by GC.
499 const int kApiStackSpace = 4; 499 const int kApiStackSpace = 4;
500 500
501 __ PrepareCallApiFunction(kApiStackSpace); 501 __ PrepareCallApiFunction(kApiStackSpace);
502 502
503 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_. 503 __ movq(StackSpaceOperand(0), rbx); // FunctionCallbackInfo::implicit_args_.
504 __ addq(rbx, Immediate(argc * kPointerSize)); 504 __ addq(rbx, Immediate((argc + kFastApiCallArguments - 1) * kPointerSize));
505 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_. 505 __ movq(StackSpaceOperand(1), rbx); // FunctionCallbackInfo::values_.
506 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_. 506 __ Set(StackSpaceOperand(2), argc); // FunctionCallbackInfo::length_.
507 // v8::Arguments::is_construct_call_. 507 // FunctionCallbackInfo::is_construct_call_.
508 __ Set(StackSpaceOperand(3), 0); 508 __ Set(StackSpaceOperand(3), 0);
509 509
510 #if defined(__MINGW64__) || defined(_WIN64) 510 #if defined(__MINGW64__) || defined(_WIN64)
511 Register arguments_arg = rcx; 511 Register arguments_arg = rcx;
512 Register callback_arg = rdx; 512 Register callback_arg = rdx;
513 #else 513 #else
514 Register arguments_arg = rdi; 514 Register arguments_arg = rdi;
515 Register callback_arg = rsi; 515 Register callback_arg = rsi;
516 #endif 516 #endif
517 517
518 // v8::InvocationCallback's argument. 518 // v8::InvocationCallback's argument.
519 __ lea(arguments_arg, StackSpaceOperand(0)); 519 __ lea(arguments_arg, StackSpaceOperand(0));
520 520
521 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 521 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
522 522
523 Operand context_restore_operand( 523 StackArgumentsAccessor args_from_rbp(rbp, kFastApiCallArguments,
524 rbp, (kFastApiCallArguments + 1 + FCA::kContextSaveIndex) * kPointerSize); 524 ARGUMENTS_DONT_CONTAIN_RECEIVER);
525 Operand return_value_operand( 525 Operand context_restore_operand = args_from_rbp.GetArgumentOperand(
526 rbp, 526 kFastApiCallArguments - 1 - FCA::kContextSaveIndex);
527 (kFastApiCallArguments + 1 + FCA::kReturnValueOffset) * kPointerSize); 527 Operand return_value_operand = args_from_rbp.GetArgumentOperand(
528 kFastApiCallArguments - 1 - FCA::kReturnValueOffset);
528 __ CallApiFunctionAndReturn( 529 __ CallApiFunctionAndReturn(
529 function_address, 530 function_address,
530 thunk_address, 531 thunk_address,
531 callback_arg, 532 callback_arg,
532 argc + kFastApiCallArguments + 1, 533 argc + kFastApiCallArguments + 1,
533 return_value_operand, 534 return_value_operand,
534 restore_context ? &context_restore_operand : NULL); 535 restore_context ? &context_restore_operand : NULL);
535 } 536 }
536 537
537 538
538 // Generate call to api function. 539 // Generate call to api function.
539 static void GenerateFastApiCall(MacroAssembler* masm, 540 static void GenerateFastApiCall(MacroAssembler* masm,
540 const CallOptimization& optimization, 541 const CallOptimization& optimization,
541 Register receiver, 542 Register receiver,
542 Register scratch, 543 Register scratch,
543 int argc, 544 int argc,
544 Register* values) { 545 Register* values) {
545 ASSERT(optimization.is_simple_api_call()); 546 ASSERT(optimization.is_simple_api_call());
546 ASSERT(!receiver.is(scratch)); 547 ASSERT(!receiver.is(scratch));
547 548
548 const int stack_space = kFastApiCallArguments + argc + 1; 549 const int fast_api_call_argc = argc + kFastApiCallArguments;
549 const int kHolderIndex = kFastApiCallArguments + 550 StackArgumentsAccessor args(rsp, fast_api_call_argc);
550 FunctionCallbackArguments::kHolderIndex; 551 // argc + 1 is the argument number before FastApiCall arguments, 1 ~ receiver
551 // Copy return value. 552 const int kHolderIndex = argc + 1 +
552 __ movq(scratch, Operand(rsp, 0)); 553 kFastApiCallArguments - 1 - FunctionCallbackArguments::kHolderIndex;
553 // Assign stack space for the call arguments. 554 __ movq(scratch, StackOperandForReturnAddress(0));
554 __ subq(rsp, Immediate(stack_space * kPointerSize)); 555 // Assign stack space for the call arguments and receiver.
555 // Move the return address on top of the stack. 556 __ subq(rsp, Immediate((fast_api_call_argc + 1) * kPointerSize));
556 __ movq(Operand(rsp, 0), scratch); 557 __ movq(StackOperandForReturnAddress(0), scratch);
557 // Write holder to stack frame. 558 // Write holder to stack frame.
558 __ movq(Operand(rsp, kHolderIndex * kPointerSize), receiver); 559 __ movq(args.GetArgumentOperand(kHolderIndex), receiver);
559 // Write receiver to stack frame. 560 __ movq(args.GetReceiverOperand(), receiver);
560 int index = stack_space;
561 __ movq(Operand(rsp, index-- * kPointerSize), receiver);
562 // Write the arguments to stack frame. 561 // Write the arguments to stack frame.
563 for (int i = 0; i < argc; i++) { 562 for (int i = 0; i < argc; i++) {
564 ASSERT(!receiver.is(values[i])); 563 ASSERT(!receiver.is(values[i]));
565 ASSERT(!scratch.is(values[i])); 564 ASSERT(!scratch.is(values[i]));
566 __ movq(Operand(rsp, index-- * kPointerSize), values[i]); 565 __ movq(args.GetArgumentOperand(i + 1), values[i]);
567 } 566 }
568 567
569 GenerateFastApiCall(masm, optimization, argc, true); 568 GenerateFastApiCall(masm, optimization, argc, true);
570 } 569 }
571 570
572 571
573 class CallInterceptorCompiler BASE_EMBEDDED { 572 class CallInterceptorCompiler BASE_EMBEDDED {
574 public: 573 public:
575 CallInterceptorCompiler(StubCompiler* stub_compiler, 574 CallInterceptorCompiler(StubCompiler* stub_compiler,
576 const ParameterCount& arguments, 575 const ParameterCount& arguments,
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1088 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
1090 Register object_reg, 1089 Register object_reg,
1091 Handle<JSObject> holder, 1090 Handle<JSObject> holder,
1092 Register holder_reg, 1091 Register holder_reg,
1093 Register scratch1, 1092 Register scratch1,
1094 Register scratch2, 1093 Register scratch2,
1095 Handle<Name> name, 1094 Handle<Name> name,
1096 int save_at_depth, 1095 int save_at_depth,
1097 Label* miss, 1096 Label* miss,
1098 PrototypeCheckType check) { 1097 PrototypeCheckType check) {
1099 const int kHolderIndex = kFastApiCallArguments +
1100 FunctionCallbackArguments::kHolderIndex;
1101 // Make sure that the type feedback oracle harvests the receiver map. 1098 // Make sure that the type feedback oracle harvests the receiver map.
1102 // TODO(svenpanne) Remove this hack when all ICs are reworked. 1099 // TODO(svenpanne) Remove this hack when all ICs are reworked.
1103 __ Move(scratch1, Handle<Map>(object->map())); 1100 __ Move(scratch1, Handle<Map>(object->map()));
1104 1101
1105 Handle<JSObject> first = object; 1102 Handle<JSObject> first = object;
1106 // Make sure there's no overlap between holder and object registers. 1103 // Make sure there's no overlap between holder and object registers.
1107 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1104 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1108 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1105 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1109 && !scratch2.is(scratch1)); 1106 && !scratch2.is(scratch1));
1110 1107
1111 // Keep track of the current object in register reg. On the first 1108 // Keep track of the current object in register reg. On the first
1112 // iteration, reg is an alias for object_reg, on later iterations, 1109 // iteration, reg is an alias for object_reg, on later iterations,
1113 // it is an alias for holder_reg. 1110 // it is an alias for holder_reg.
1114 Register reg = object_reg; 1111 Register reg = object_reg;
1115 int depth = 0; 1112 int depth = 0;
1116 1113
1114 StackArgumentsAccessor args(rsp, kFastApiCallArguments,
1115 ARGUMENTS_DONT_CONTAIN_RECEIVER);
1116 const int kHolderIndex = kFastApiCallArguments - 1 -
1117 FunctionCallbackArguments::kHolderIndex;
1118
1117 if (save_at_depth == depth) { 1119 if (save_at_depth == depth) {
1118 __ movq(Operand(rsp, kHolderIndex * kPointerSize), object_reg); 1120 __ movq(args.GetArgumentOperand(kHolderIndex), object_reg);
1119 } 1121 }
1120 1122
1121 // Check the maps in the prototype chain. 1123 // Check the maps in the prototype chain.
1122 // Traverse the prototype chain from the object and do map checks. 1124 // Traverse the prototype chain from the object and do map checks.
1123 Handle<JSObject> current = object; 1125 Handle<JSObject> current = object;
1124 while (!current.is_identical_to(holder)) { 1126 while (!current.is_identical_to(holder)) {
1125 ++depth; 1127 ++depth;
1126 1128
1127 // Only global objects and objects that do not require access 1129 // Only global objects and objects that do not require access
1128 // checks are allowed in stubs. 1130 // checks are allowed in stubs.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 // The prototype is in new space; we cannot store a reference to it 1170 // The prototype is in new space; we cannot store a reference to it
1169 // in the code. Load it from the map. 1171 // in the code. Load it from the map.
1170 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1172 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1171 } else { 1173 } else {
1172 // The prototype is in old space; load it directly. 1174 // The prototype is in old space; load it directly.
1173 __ Move(reg, prototype); 1175 __ Move(reg, prototype);
1174 } 1176 }
1175 } 1177 }
1176 1178
1177 if (save_at_depth == depth) { 1179 if (save_at_depth == depth) {
1178 __ movq(Operand(rsp, kHolderIndex * kPointerSize), reg); 1180 __ movq(args.GetArgumentOperand(kHolderIndex), reg);
1179 } 1181 }
1180 1182
1181 // Go to the next object in the prototype chain. 1183 // Go to the next object in the prototype chain.
1182 current = prototype; 1184 current = prototype;
1183 } 1185 }
1184 ASSERT(current.is_identical_to(holder)); 1186 ASSERT(current.is_identical_to(holder));
1185 1187
1186 // Log the check depth. 1188 // Log the check depth.
1187 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1189 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1188 1190
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 } 1328 }
1327 1329
1328 1330
1329 void BaseLoadStubCompiler::GenerateLoadCallback( 1331 void BaseLoadStubCompiler::GenerateLoadCallback(
1330 Register reg, 1332 Register reg,
1331 Handle<ExecutableAccessorInfo> callback) { 1333 Handle<ExecutableAccessorInfo> callback) {
1332 // Insert additional parameters into the stack frame above return address. 1334 // Insert additional parameters into the stack frame above return address.
1333 ASSERT(!scratch4().is(reg)); 1335 ASSERT(!scratch4().is(reg));
1334 __ PopReturnAddressTo(scratch4()); 1336 __ PopReturnAddressTo(scratch4());
1335 1337
1336 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 0); 1338 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
1337 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == -1); 1339 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
1338 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == -2); 1340 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
1339 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == -3); 1341 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
1340 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == -4); 1342 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
1341 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == -5); 1343 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
1344 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
1342 __ push(receiver()); // receiver 1345 __ push(receiver()); // receiver
1343 if (heap()->InNewSpace(callback->data())) { 1346 if (heap()->InNewSpace(callback->data())) {
1344 ASSERT(!scratch2().is(reg)); 1347 ASSERT(!scratch2().is(reg));
1345 __ Move(scratch2(), callback); 1348 __ Move(scratch2(), callback);
1346 __ push(FieldOperand(scratch2(), 1349 __ push(FieldOperand(scratch2(),
1347 ExecutableAccessorInfo::kDataOffset)); // data 1350 ExecutableAccessorInfo::kDataOffset)); // data
1348 } else { 1351 } else {
1349 __ Push(Handle<Object>(callback->data(), isolate())); 1352 __ Push(Handle<Object>(callback->data(), isolate()));
1350 } 1353 }
1351 ASSERT(!kScratchRegister.is(reg)); 1354 ASSERT(!kScratchRegister.is(reg));
1352 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 1355 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
1353 __ push(kScratchRegister); // return value 1356 __ push(kScratchRegister); // return value
1354 __ push(kScratchRegister); // return value default 1357 __ push(kScratchRegister); // return value default
1355 __ PushAddress(ExternalReference::isolate_address(isolate())); 1358 __ PushAddress(ExternalReference::isolate_address(isolate()));
1356 __ push(reg); // holder 1359 __ push(reg); // holder
1357 __ push(name()); // name 1360 __ push(name()); // name
1358 // Save a pointer to where we pushed the arguments pointer. This will be 1361 // Save a pointer to where we pushed the arguments pointer. This will be
1359 // passed as the const ExecutableAccessorInfo& to the C++ callback. 1362 // passed as the const PropertyAccessorInfo& to the C++ callback.
1360 1363
1361 Address getter_address = v8::ToCData<Address>(callback->getter()); 1364 Address getter_address = v8::ToCData<Address>(callback->getter());
1362 1365
1363 #if defined(__MINGW64__) || defined(_WIN64) 1366 #if defined(__MINGW64__) || defined(_WIN64)
1364 Register getter_arg = r8; 1367 Register getter_arg = r8;
1365 Register accessor_info_arg = rdx; 1368 Register accessor_info_arg = rdx;
1366 Register name_arg = rcx; 1369 Register name_arg = rcx;
1367 #else 1370 #else
1368 Register getter_arg = rdx; 1371 Register getter_arg = rdx;
1369 Register accessor_info_arg = rsi; 1372 Register accessor_info_arg = rsi;
1370 Register name_arg = rdi; 1373 Register name_arg = rdi;
1371 #endif 1374 #endif
1372 1375
1373 ASSERT(!name_arg.is(scratch4())); 1376 ASSERT(!name_arg.is(scratch4()));
1374 __ movq(name_arg, rsp); 1377 __ movq(name_arg, rsp);
1375 __ PushReturnAddressFrom(scratch4()); 1378 __ PushReturnAddressFrom(scratch4());
1376 1379
1377 // v8::Arguments::values_ and handler for name. 1380 // v8::Arguments::values_ and handler for name.
1378 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1; 1381 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1;
1379 1382
1380 // Allocate v8::AccessorInfo in non-GCed stack space. 1383 // Allocate v8::AccessorInfo in non-GCed stack space.
1381 const int kArgStackSpace = 1; 1384 const int kArgStackSpace = 1;
1382 1385
1383 __ PrepareCallApiFunction(kArgStackSpace); 1386 __ PrepareCallApiFunction(kArgStackSpace);
1384 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 1387 __ lea(rax, Operand(name_arg, 1 * kPointerSize));
1385 __ lea(rax, Operand(name_arg, 6 * kPointerSize));
1386 1388
1387 // v8::AccessorInfo::args_. 1389 // v8::PropertyAccessorInfo::args_.
1388 __ movq(StackSpaceOperand(0), rax); 1390 __ movq(StackSpaceOperand(0), rax);
1389 1391
1390 // The context register (rsi) has been saved in PrepareCallApiFunction and 1392 // The context register (rsi) has been saved in PrepareCallApiFunction and
1391 // could be used to pass arguments. 1393 // could be used to pass arguments.
1392 __ lea(accessor_info_arg, StackSpaceOperand(0)); 1394 __ lea(accessor_info_arg, StackSpaceOperand(0));
1393 1395
1394 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); 1396 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
1395 1397
1398 // The name handler is counted as an argument.
1399 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength);
1400 Operand return_value_operand = args.GetArgumentOperand(
1401 PropertyCallbackArguments::kArgsLength - 1 -
1402 PropertyCallbackArguments::kReturnValueOffset);
1396 __ CallApiFunctionAndReturn(getter_address, 1403 __ CallApiFunctionAndReturn(getter_address,
1397 thunk_address, 1404 thunk_address,
1398 getter_arg, 1405 getter_arg,
1399 kStackSpace, 1406 kStackSpace,
1400 Operand(rbp, 6 * kPointerSize), 1407 return_value_operand,
1401 NULL); 1408 NULL);
1402 } 1409 }
1403 1410
1404 1411
1405 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1412 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1406 // Return the constant value. 1413 // Return the constant value.
1407 __ LoadObject(rax, value); 1414 __ LoadObject(rax, value);
1408 __ ret(0); 1415 __ ret(0);
1409 } 1416 }
1410 1417
(...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after
2184 // If the object is not a JSObject or we got an unexpected number of 2191 // If the object is not a JSObject or we got an unexpected number of
2185 // arguments, bail out to the regular call. 2192 // arguments, bail out to the regular call.
2186 const int argc = arguments().immediate(); 2193 const int argc = arguments().immediate();
2187 StackArgumentsAccessor args(rsp, argc); 2194 StackArgumentsAccessor args(rsp, argc);
2188 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2195 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2189 2196
2190 Label miss; 2197 Label miss;
2191 GenerateNameCheck(name, &miss); 2198 GenerateNameCheck(name, &miss);
2192 2199
2193 if (cell.is_null()) { 2200 if (cell.is_null()) {
2194 __ movq(rdx, args.GetArgumentOperand(argc - 1)); 2201 __ movq(rdx, args.GetReceiverOperand());
2195 __ JumpIfSmi(rdx, &miss); 2202 __ JumpIfSmi(rdx, &miss);
2196 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2203 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
2197 name, &miss); 2204 name, &miss);
2198 } else { 2205 } else {
2199 ASSERT(cell->value() == *function); 2206 ASSERT(cell->value() == *function);
2200 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2207 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2201 &miss); 2208 &miss);
2202 GenerateLoadFunctionFromCell(cell, function, &miss); 2209 GenerateLoadFunctionFromCell(cell, function, &miss);
2203 } 2210 }
2204 2211
2205 // Load the char code argument. 2212 // Load the char code argument.
2206 Register code = rbx; 2213 Register code = rbx;
2207 __ movq(code, args.GetArgumentOperand(argc)); 2214 __ movq(code, args.GetArgumentOperand(1));
2208 2215
2209 // Check the code is a smi. 2216 // Check the code is a smi.
2210 Label slow; 2217 Label slow;
2211 __ JumpIfNotSmi(code, &slow); 2218 __ JumpIfNotSmi(code, &slow);
2212 2219
2213 // Convert the smi code to uint16. 2220 // Convert the smi code to uint16.
2214 __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); 2221 __ SmiAndConstant(code, code, Smi::FromInt(0xffff));
2215 2222
2216 StringCharFromCodeGenerator generator(code, rax); 2223 StringCharFromCodeGenerator generator(code, rax);
2217 generator.GenerateFast(masm()); 2224 generator.GenerateFast(masm());
(...skipping 29 matching lines...) Expand all
2247 Handle<String> name, 2254 Handle<String> name,
2248 Code::StubType type) { 2255 Code::StubType type) {
2249 // ----------- S t a t e ------------- 2256 // ----------- S t a t e -------------
2250 // -- rcx : name 2257 // -- rcx : name
2251 // -- rsp[0] : return address 2258 // -- rsp[0] : return address
2252 // -- rsp[(argc - n) * 4] : arg[n] (zero-based) 2259 // -- rsp[(argc - n) * 4] : arg[n] (zero-based)
2253 // -- ... 2260 // -- ...
2254 // -- rsp[(argc + 1) * 4] : receiver 2261 // -- rsp[(argc + 1) * 4] : receiver
2255 // ----------------------------------- 2262 // -----------------------------------
2256 const int argc = arguments().immediate(); 2263 const int argc = arguments().immediate();
2264 StackArgumentsAccessor args(rsp, argc);
2257 2265
2258 // If the object is not a JSObject or we got an unexpected number of 2266 // If the object is not a JSObject or we got an unexpected number of
2259 // arguments, bail out to the regular call. 2267 // arguments, bail out to the regular call.
2260 if (!object->IsJSObject() || argc != 1) { 2268 if (!object->IsJSObject() || argc != 1) {
2261 return Handle<Code>::null(); 2269 return Handle<Code>::null();
2262 } 2270 }
2263 2271
2264 Label miss; 2272 Label miss;
2265 GenerateNameCheck(name, &miss); 2273 GenerateNameCheck(name, &miss);
2266 2274
2267 if (cell.is_null()) { 2275 if (cell.is_null()) {
2268 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2276 __ movq(rdx, args.GetReceiverOperand());
2269 2277
2270 STATIC_ASSERT(kSmiTag == 0); 2278 STATIC_ASSERT(kSmiTag == 0);
2271 __ JumpIfSmi(rdx, &miss); 2279 __ JumpIfSmi(rdx, &miss);
2272 2280
2273 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2281 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
2274 name, &miss); 2282 name, &miss);
2275 } else { 2283 } else {
2276 ASSERT(cell->value() == *function); 2284 ASSERT(cell->value() == *function);
2277 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2285 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2278 &miss); 2286 &miss);
2279 GenerateLoadFunctionFromCell(cell, function, &miss); 2287 GenerateLoadFunctionFromCell(cell, function, &miss);
2280 } 2288 }
2281 2289
2282 // Load the (only) argument into rax. 2290 // Load the (only) argument into rax.
2283 __ movq(rax, Operand(rsp, 1 * kPointerSize)); 2291 __ movq(rax, args.GetArgumentOperand(1));
2284 2292
2285 // Check if the argument is a smi. 2293 // Check if the argument is a smi.
2286 Label smi; 2294 Label smi;
2287 STATIC_ASSERT(kSmiTag == 0); 2295 STATIC_ASSERT(kSmiTag == 0);
2288 __ JumpIfSmi(rax, &smi); 2296 __ JumpIfSmi(rax, &smi);
2289 2297
2290 // Check if the argument is a heap number and load its value into xmm0. 2298 // Check if the argument is a heap number and load its value into xmm0.
2291 Label slow; 2299 Label slow;
2292 __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK); 2300 __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK);
2293 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); 2301 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2340 __ andpd(xmm1, xmm2); 2348 __ andpd(xmm1, xmm2);
2341 __ subsd(xmm0, xmm1); 2349 __ subsd(xmm0, xmm1);
2342 2350
2343 // Return a new heap number. 2351 // Return a new heap number.
2344 __ AllocateHeapNumber(rax, rbx, &slow); 2352 __ AllocateHeapNumber(rax, rbx, &slow);
2345 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); 2353 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
2346 __ ret(2 * kPointerSize); 2354 __ ret(2 * kPointerSize);
2347 2355
2348 // Return the argument (when it's an already round heap number). 2356 // Return the argument (when it's an already round heap number).
2349 __ bind(&already_round); 2357 __ bind(&already_round);
2350 __ movq(rax, Operand(rsp, 1 * kPointerSize)); 2358 __ movq(rax, args.GetArgumentOperand(1));
2351 __ ret(2 * kPointerSize); 2359 __ ret(2 * kPointerSize);
2352 2360
2353 // Tail call the full function. We do not have to patch the receiver 2361 // Tail call the full function. We do not have to patch the receiver
2354 // because the function makes no use of it. 2362 // because the function makes no use of it.
2355 __ bind(&slow); 2363 __ bind(&slow);
2356 ParameterCount expected(function); 2364 ParameterCount expected(function);
2357 __ InvokeFunction(function, expected, arguments(), 2365 __ InvokeFunction(function, expected, arguments(),
2358 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2366 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2359 2367
2360 __ bind(&miss); 2368 __ bind(&miss);
(...skipping 23 matching lines...) Expand all
2384 // If the object is not a JSObject or we got an unexpected number of 2392 // If the object is not a JSObject or we got an unexpected number of
2385 // arguments, bail out to the regular call. 2393 // arguments, bail out to the regular call.
2386 const int argc = arguments().immediate(); 2394 const int argc = arguments().immediate();
2387 StackArgumentsAccessor args(rsp, argc); 2395 StackArgumentsAccessor args(rsp, argc);
2388 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2396 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2389 2397
2390 Label miss; 2398 Label miss;
2391 GenerateNameCheck(name, &miss); 2399 GenerateNameCheck(name, &miss);
2392 2400
2393 if (cell.is_null()) { 2401 if (cell.is_null()) {
2394 __ movq(rdx, args.GetArgumentOperand(argc - 1)); 2402 __ movq(rdx, args.GetReceiverOperand());
2395 __ JumpIfSmi(rdx, &miss); 2403 __ JumpIfSmi(rdx, &miss);
2396 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2404 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
2397 name, &miss); 2405 name, &miss);
2398 } else { 2406 } else {
2399 ASSERT(cell->value() == *function); 2407 ASSERT(cell->value() == *function);
2400 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2408 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2401 &miss); 2409 &miss);
2402 GenerateLoadFunctionFromCell(cell, function, &miss); 2410 GenerateLoadFunctionFromCell(cell, function, &miss);
2403 } 2411 }
2404 // Load the (only) argument into rax. 2412 // Load the (only) argument into rax.
2405 __ movq(rax, args.GetArgumentOperand(argc)); 2413 __ movq(rax, args.GetArgumentOperand(1));
2406 2414
2407 // Check if the argument is a smi. 2415 // Check if the argument is a smi.
2408 Label not_smi; 2416 Label not_smi;
2409 STATIC_ASSERT(kSmiTag == 0); 2417 STATIC_ASSERT(kSmiTag == 0);
2410 __ JumpIfNotSmi(rax, &not_smi); 2418 __ JumpIfNotSmi(rax, &not_smi);
2411 2419
2412 // Branchless abs implementation, refer to below: 2420 // Branchless abs implementation, refer to below:
2413 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs 2421 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
2414 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0 2422 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
2415 // otherwise. 2423 // otherwise.
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
3170 // ----------------------------------- 3178 // -----------------------------------
3171 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3179 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3172 } 3180 }
3173 3181
3174 3182
3175 #undef __ 3183 #undef __
3176 3184
3177 } } // namespace v8::internal 3185 } } // namespace v8::internal
3178 3186
3179 #endif // V8_TARGET_ARCH_X64 3187 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/cctest/cctest.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698