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

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

Issue 24205004: Rollback trunk to 3.21.16.2 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
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') | test/cctest/test-accessors.cc » ('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 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 STATIC_ASSERT(kNotStringTag != 0); 297 STATIC_ASSERT(kNotStringTag != 0);
298 __ testl(scratch, Immediate(kNotStringTag)); 298 __ testl(scratch, Immediate(kNotStringTag));
299 __ j(not_zero, non_string_object); 299 __ j(not_zero, non_string_object);
300 } 300 }
301 301
302 302
303 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, 303 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
304 Register receiver, 304 Register receiver,
305 Register scratch1, 305 Register scratch1,
306 Register scratch2, 306 Register scratch2,
307 Label* miss) { 307 Label* miss,
308 bool support_wrappers) {
308 Label check_wrapper; 309 Label check_wrapper;
309 310
310 // Check if the object is a string leaving the instance type in the 311 // Check if the object is a string leaving the instance type in the
311 // scratch register. 312 // scratch register.
312 GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper); 313 GenerateStringCheck(masm, receiver, scratch1, miss,
314 support_wrappers ? &check_wrapper : miss);
313 315
314 // Load length directly from the string. 316 // Load length directly from the string.
315 __ movq(rax, FieldOperand(receiver, String::kLengthOffset)); 317 __ movq(rax, FieldOperand(receiver, String::kLengthOffset));
316 __ ret(0); 318 __ ret(0);
317 319
318 // Check if the object is a JSValue wrapper. 320 if (support_wrappers) {
319 __ bind(&check_wrapper); 321 // Check if the object is a JSValue wrapper.
320 __ cmpl(scratch1, Immediate(JS_VALUE_TYPE)); 322 __ bind(&check_wrapper);
321 __ j(not_equal, miss); 323 __ cmpl(scratch1, Immediate(JS_VALUE_TYPE));
324 __ j(not_equal, miss);
322 325
323 // Check if the wrapped value is a string and load the length 326 // Check if the wrapped value is a string and load the length
324 // directly if it is. 327 // directly if it is.
325 __ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset)); 328 __ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
326 GenerateStringCheck(masm, scratch2, scratch1, miss, miss); 329 GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
327 __ movq(rax, FieldOperand(scratch2, String::kLengthOffset)); 330 __ movq(rax, FieldOperand(scratch2, String::kLengthOffset));
328 __ ret(0); 331 __ ret(0);
332 }
329 } 333 }
330 334
331 335
332 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, 336 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
333 Register receiver, 337 Register receiver,
334 Register result, 338 Register result,
335 Register scratch, 339 Register scratch,
336 Label* miss_label) { 340 Label* miss_label) {
337 __ TryGetFunctionPrototype(receiver, result, miss_label); 341 __ TryGetFunctionPrototype(receiver, result, miss_label);
338 if (!result.is(rax)) __ movq(rax, result); 342 if (!result.is(rax)) __ movq(rax, result);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 __ movq(scratch, StackOperandForReturnAddress(0)); 440 __ movq(scratch, StackOperandForReturnAddress(0));
437 __ movq(StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize), 441 __ movq(StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize),
438 scratch); 442 scratch);
439 __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments)); 443 __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments));
440 } 444 }
441 445
442 446
443 // Generates call to API function. 447 // Generates call to API function.
444 static void GenerateFastApiCall(MacroAssembler* masm, 448 static void GenerateFastApiCall(MacroAssembler* masm,
445 const CallOptimization& optimization, 449 const CallOptimization& optimization,
446 int argc, 450 int argc) {
447 bool restore_context) {
448 // ----------- S t a t e ------------- 451 // ----------- S t a t e -------------
449 // -- rsp[0] : return address 452 // -- rsp[0] : return address
450 // -- rsp[8] : context save 453 // -- rsp[8] : object passing the type check
451 // -- rsp[16] : object passing the type check
452 // (last fast api call extra argument, 454 // (last fast api call extra argument,
453 // set by CheckPrototypes) 455 // set by CheckPrototypes)
454 // -- rsp[24] : api function 456 // -- rsp[16] : api function
455 // (first fast api call extra argument) 457 // (first fast api call extra argument)
456 // -- rsp[32] : api call data 458 // -- rsp[24] : api call data
457 // -- rsp[40] : isolate 459 // -- rsp[32] : isolate
458 // -- rsp[48] : ReturnValue default value 460 // -- rsp[40] : ReturnValue default value
459 // -- rsp[56] : ReturnValue 461 // -- rsp[48] : ReturnValue
460 // 462 //
461 // -- rsp[64] : last argument 463 // -- rsp[56] : last argument
462 // -- ... 464 // -- ...
463 // -- rsp[(argc + 7) * 8] : first argument 465 // -- rsp[(argc + 6) * 8] : first argument
464 // -- rsp[(argc + 8) * 8] : receiver 466 // -- rsp[(argc + 7) * 8] : receiver
465 // ----------------------------------- 467 // -----------------------------------
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. 468 // Get the function and setup the context.
473 Handle<JSFunction> function = optimization.constant_function(); 469 Handle<JSFunction> function = optimization.constant_function();
474 __ LoadHeapObject(rdi, function); 470 __ LoadHeapObject(rdi, function);
475 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 471 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
472
473 int api_call_argc = argc + kFastApiCallArguments;
474 StackArgumentsAccessor args(rsp, api_call_argc);
475
476 // Pass the additional arguments. 476 // Pass the additional arguments.
477 __ movq(args.GetArgumentOperand(api_call_argc - 2), rdi); 477 __ movq(args.GetArgumentOperand(api_call_argc - 1), rdi);
478 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 478 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
479 Handle<Object> call_data(api_call_info->data(), masm->isolate()); 479 Handle<Object> call_data(api_call_info->data(), masm->isolate());
480 if (masm->isolate()->heap()->InNewSpace(*call_data)) { 480 if (masm->isolate()->heap()->InNewSpace(*call_data)) {
481 __ Move(rcx, api_call_info); 481 __ Move(rcx, api_call_info);
482 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); 482 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
483 __ movq(args.GetArgumentOperand(api_call_argc - 3), rbx); 483 __ movq(args.GetArgumentOperand(api_call_argc - 2), rbx);
484 } else { 484 } else {
485 __ Move(args.GetArgumentOperand(api_call_argc - 3), call_data); 485 __ Move(args.GetArgumentOperand(api_call_argc - 2), call_data);
486 } 486 }
487 __ movq(kScratchRegister, 487 __ movq(kScratchRegister,
488 ExternalReference::isolate_address(masm->isolate())); 488 ExternalReference::isolate_address(masm->isolate()));
489 __ movq(args.GetArgumentOperand(api_call_argc - 3), kScratchRegister);
490 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
489 __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister); 491 __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
490 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
491 __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister); 492 __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister);
492 __ movq(args.GetArgumentOperand(api_call_argc - 6), kScratchRegister);
493 493
494 // Prepare arguments. 494 // Prepare arguments.
495 STATIC_ASSERT(kFastApiCallArguments == 7); 495 STATIC_ASSERT(kFastApiCallArguments == 6);
496 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); 496 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize));
497 497
498 // Function address is a foreign pointer outside V8's heap. 498 // Function address is a foreign pointer outside V8's heap.
499 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 499 Address function_address = v8::ToCData<Address>(api_call_info->callback());
500 500
501 #if defined(__MINGW64__) || defined(_WIN64)
502 Register arguments_arg = rcx;
503 Register callback_arg = rdx;
504 #else
505 Register arguments_arg = rdi;
506 Register callback_arg = rsi;
507 #endif
508
501 // Allocate the v8::Arguments structure in the arguments' space since 509 // Allocate the v8::Arguments structure in the arguments' space since
502 // it's not controlled by GC. 510 // it's not controlled by GC.
503 const int kApiStackSpace = 4; 511 const int kApiStackSpace = 4;
504 512
505 __ PrepareCallApiFunction(kApiStackSpace); 513 __ PrepareCallApiFunction(kApiStackSpace);
506 514
507 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_. 515 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_.
508 __ addq(rbx, Immediate(argc * kPointerSize)); 516 __ addq(rbx, Immediate(argc * kPointerSize));
509 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_. 517 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_.
510 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_. 518 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_.
511 // v8::Arguments::is_construct_call_. 519 // v8::Arguments::is_construct_call_.
512 __ Set(StackSpaceOperand(3), 0); 520 __ Set(StackSpaceOperand(3), 0);
513 521
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. 522 // v8::InvocationCallback's argument.
523 __ lea(arguments_arg, StackSpaceOperand(0)); 523 __ lea(arguments_arg, StackSpaceOperand(0));
524 524
525 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 525 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
526 526
527 Operand context_restore_operand(rbp, 2 * kPointerSize);
528 Operand return_value_operand(
529 rbp, (kFastApiCallArguments + 1) * kPointerSize);
530 __ CallApiFunctionAndReturn(function_address, 527 __ CallApiFunctionAndReturn(function_address,
531 thunk_address, 528 thunk_address,
532 callback_arg, 529 callback_arg,
533 api_call_argc + 1, 530 api_call_argc + 1,
534 return_value_operand, 531 kFastApiCallArguments + 1);
535 restore_context ?
536 &context_restore_operand : NULL);
537 } 532 }
538 533
539 534
540 // Generate call to api function. 535 // Generate call to api function.
541 static void GenerateFastApiCall(MacroAssembler* masm, 536 static void GenerateFastApiCall(MacroAssembler* masm,
542 const CallOptimization& optimization, 537 const CallOptimization& optimization,
543 Register receiver, 538 Register receiver,
544 Register scratch, 539 Register scratch,
545 int argc, 540 int argc,
546 Register* values) { 541 Register* values) {
547 ASSERT(optimization.is_simple_api_call()); 542 ASSERT(optimization.is_simple_api_call());
548 ASSERT(!receiver.is(scratch)); 543 ASSERT(!receiver.is(scratch));
549 544
550 const int stack_space = kFastApiCallArguments + argc + 1; 545 const int stack_space = kFastApiCallArguments + argc + 1;
551 const int kHolderIndex = kFastApiCallArguments +
552 FunctionCallbackArguments::kHolderIndex;
553 // Copy return value. 546 // Copy return value.
554 __ movq(scratch, Operand(rsp, 0)); 547 __ movq(scratch, Operand(rsp, 0));
555 // Assign stack space for the call arguments. 548 // Assign stack space for the call arguments.
556 __ subq(rsp, Immediate(stack_space * kPointerSize)); 549 __ subq(rsp, Immediate(stack_space * kPointerSize));
557 // Move the return address on top of the stack. 550 // Move the return address on top of the stack.
558 __ movq(Operand(rsp, 0), scratch); 551 __ movq(Operand(rsp, 0), scratch);
559 // Write holder to stack frame. 552 // Write holder to stack frame.
560 __ movq(Operand(rsp, kHolderIndex * kPointerSize), receiver); 553 __ movq(Operand(rsp, 1 * kPointerSize), receiver);
561 // Write receiver to stack frame. 554 // Write receiver to stack frame.
562 int index = stack_space; 555 int index = stack_space;
563 __ movq(Operand(rsp, index-- * kPointerSize), receiver); 556 __ movq(Operand(rsp, index-- * kPointerSize), receiver);
564 // Write the arguments to stack frame. 557 // Write the arguments to stack frame.
565 for (int i = 0; i < argc; i++) { 558 for (int i = 0; i < argc; i++) {
566 ASSERT(!receiver.is(values[i])); 559 ASSERT(!receiver.is(values[i]));
567 ASSERT(!scratch.is(values[i])); 560 ASSERT(!scratch.is(values[i]));
568 __ movq(Operand(rsp, index-- * kPointerSize), values[i]); 561 __ movq(Operand(rsp, index-- * kPointerSize), values[i]);
569 } 562 }
570 563
571 GenerateFastApiCall(masm, optimization, argc, true); 564 GenerateFastApiCall(masm, optimization, argc);
572 } 565 }
573 566
574 567
575 class CallInterceptorCompiler BASE_EMBEDDED { 568 class CallInterceptorCompiler BASE_EMBEDDED {
576 public: 569 public:
577 CallInterceptorCompiler(StubCompiler* stub_compiler, 570 CallInterceptorCompiler(StubCompiler* stub_compiler,
578 const ParameterCount& arguments, 571 const ParameterCount& arguments,
579 Register name, 572 Register name,
580 Code::ExtraICState extra_ic_state) 573 Code::ExtraICState extra_ic_state)
581 : stub_compiler_(stub_compiler), 574 : stub_compiler_(stub_compiler),
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 } else { 668 } else {
676 // CheckPrototypes has a side effect of fetching a 'holder' 669 // CheckPrototypes has a side effect of fetching a 'holder'
677 // for API (object which is instanceof for the signature). It's 670 // for API (object which is instanceof for the signature). It's
678 // safe to omit it here, as if present, it should be fetched 671 // safe to omit it here, as if present, it should be fetched
679 // by the previous CheckPrototypes. 672 // by the previous CheckPrototypes.
680 ASSERT(depth2 == kInvalidProtoDepth); 673 ASSERT(depth2 == kInvalidProtoDepth);
681 } 674 }
682 675
683 // Invoke function. 676 // Invoke function.
684 if (can_do_fast_api_call) { 677 if (can_do_fast_api_call) {
685 GenerateFastApiCall(masm, optimization, arguments_.immediate(), false); 678 GenerateFastApiCall(masm, optimization, arguments_.immediate());
686 } else { 679 } else {
687 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 680 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
688 ? CALL_AS_FUNCTION 681 ? CALL_AS_FUNCTION
689 : CALL_AS_METHOD; 682 : CALL_AS_METHOD;
690 Handle<JSFunction> fun = optimization.constant_function(); 683 Handle<JSFunction> fun = optimization.constant_function();
691 ParameterCount expected(fun); 684 ParameterCount expected(fun);
692 __ InvokeFunction(fun, expected, arguments_, 685 __ InvokeFunction(fun, expected, arguments_,
693 JUMP_FUNCTION, NullCallWrapper(), call_kind); 686 JUMP_FUNCTION, NullCallWrapper(), call_kind);
694 } 687 }
695 688
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 } else if (FLAG_track_fields && representation.IsSmi()) { 835 } else if (FLAG_track_fields && representation.IsSmi()) {
843 __ JumpIfNotSmi(value_reg, miss_label); 836 __ JumpIfNotSmi(value_reg, miss_label);
844 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 837 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
845 __ JumpIfSmi(value_reg, miss_label); 838 __ JumpIfSmi(value_reg, miss_label);
846 } else if (FLAG_track_double_fields && representation.IsDouble()) { 839 } else if (FLAG_track_double_fields && representation.IsDouble()) {
847 Label do_store, heap_number; 840 Label do_store, heap_number;
848 __ AllocateHeapNumber(storage_reg, scratch1, slow); 841 __ AllocateHeapNumber(storage_reg, scratch1, slow);
849 842
850 __ JumpIfNotSmi(value_reg, &heap_number); 843 __ JumpIfNotSmi(value_reg, &heap_number);
851 __ SmiToInteger32(scratch1, value_reg); 844 __ SmiToInteger32(scratch1, value_reg);
852 __ Cvtlsi2sd(xmm0, scratch1); 845 __ cvtlsi2sd(xmm0, scratch1);
853 __ jmp(&do_store); 846 __ jmp(&do_store);
854 847
855 __ bind(&heap_number); 848 __ bind(&heap_number);
856 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 849 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
857 miss_label, DONT_DO_SMI_CHECK); 850 miss_label, DONT_DO_SMI_CHECK);
858 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 851 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
859 852
860 __ bind(&do_store); 853 __ bind(&do_store);
861 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 854 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
862 } 855 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 __ movq(scratch1, 989 __ movq(scratch1,
997 FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 990 FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
998 int offset = index * kPointerSize + FixedArray::kHeaderSize; 991 int offset = index * kPointerSize + FixedArray::kHeaderSize;
999 __ movq(scratch1, FieldOperand(scratch1, offset)); 992 __ movq(scratch1, FieldOperand(scratch1, offset));
1000 } 993 }
1001 994
1002 // Store the value into the storage. 995 // Store the value into the storage.
1003 Label do_store, heap_number; 996 Label do_store, heap_number;
1004 __ JumpIfNotSmi(value_reg, &heap_number); 997 __ JumpIfNotSmi(value_reg, &heap_number);
1005 __ SmiToInteger32(scratch2, value_reg); 998 __ SmiToInteger32(scratch2, value_reg);
1006 __ Cvtlsi2sd(xmm0, scratch2); 999 __ cvtlsi2sd(xmm0, scratch2);
1007 __ jmp(&do_store); 1000 __ jmp(&do_store);
1008 1001
1009 __ bind(&heap_number); 1002 __ bind(&heap_number);
1010 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 1003 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
1011 miss_label, DONT_DO_SMI_CHECK); 1004 miss_label, DONT_DO_SMI_CHECK);
1012 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 1005 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
1013 __ bind(&do_store); 1006 __ bind(&do_store);
1014 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); 1007 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0);
1015 // Return the value (register rax). 1008 // Return the value (register rax).
1016 ASSERT(value_reg.is(rax)); 1009 ASSERT(value_reg.is(rax));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1084 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
1092 Register object_reg, 1085 Register object_reg,
1093 Handle<JSObject> holder, 1086 Handle<JSObject> holder,
1094 Register holder_reg, 1087 Register holder_reg,
1095 Register scratch1, 1088 Register scratch1,
1096 Register scratch2, 1089 Register scratch2,
1097 Handle<Name> name, 1090 Handle<Name> name,
1098 int save_at_depth, 1091 int save_at_depth,
1099 Label* miss, 1092 Label* miss,
1100 PrototypeCheckType check) { 1093 PrototypeCheckType check) {
1101 const int kHolderIndex = kFastApiCallArguments +
1102 FunctionCallbackArguments::kHolderIndex;
1103 // Make sure that the type feedback oracle harvests the receiver map. 1094 // Make sure that the type feedback oracle harvests the receiver map.
1104 // TODO(svenpanne) Remove this hack when all ICs are reworked. 1095 // TODO(svenpanne) Remove this hack when all ICs are reworked.
1105 __ Move(scratch1, Handle<Map>(object->map())); 1096 __ Move(scratch1, Handle<Map>(object->map()));
1106 1097
1107 Handle<JSObject> first = object; 1098 Handle<JSObject> first = object;
1108 // Make sure there's no overlap between holder and object registers. 1099 // Make sure there's no overlap between holder and object registers.
1109 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1100 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1110 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1101 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1111 && !scratch2.is(scratch1)); 1102 && !scratch2.is(scratch1));
1112 1103
1113 // Keep track of the current object in register reg. On the first 1104 // Keep track of the current object in register reg. On the first
1114 // iteration, reg is an alias for object_reg, on later iterations, 1105 // iteration, reg is an alias for object_reg, on later iterations,
1115 // it is an alias for holder_reg. 1106 // it is an alias for holder_reg.
1116 Register reg = object_reg; 1107 Register reg = object_reg;
1117 int depth = 0; 1108 int depth = 0;
1118 1109
1119 if (save_at_depth == depth) { 1110 if (save_at_depth == depth) {
1120 __ movq(Operand(rsp, kHolderIndex * kPointerSize), object_reg); 1111 __ movq(Operand(rsp, kPCOnStackSize), object_reg);
1121 } 1112 }
1122 1113
1123 // Check the maps in the prototype chain. 1114 // Check the maps in the prototype chain.
1124 // Traverse the prototype chain from the object and do map checks. 1115 // Traverse the prototype chain from the object and do map checks.
1125 Handle<JSObject> current = object; 1116 Handle<JSObject> current = object;
1126 while (!current.is_identical_to(holder)) { 1117 while (!current.is_identical_to(holder)) {
1127 ++depth; 1118 ++depth;
1128 1119
1129 // Only global objects and objects that do not require access 1120 // Only global objects and objects that do not require access
1130 // checks are allowed in stubs. 1121 // 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 1161 // The prototype is in new space; we cannot store a reference to it
1171 // in the code. Load it from the map. 1162 // in the code. Load it from the map.
1172 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1163 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1173 } else { 1164 } else {
1174 // The prototype is in old space; load it directly. 1165 // The prototype is in old space; load it directly.
1175 __ Move(reg, prototype); 1166 __ Move(reg, prototype);
1176 } 1167 }
1177 } 1168 }
1178 1169
1179 if (save_at_depth == depth) { 1170 if (save_at_depth == depth) {
1180 __ movq(Operand(rsp, kHolderIndex * kPointerSize), reg); 1171 __ movq(Operand(rsp, kPCOnStackSize), reg);
1181 } 1172 }
1182 1173
1183 // Go to the next object in the prototype chain. 1174 // Go to the next object in the prototype chain.
1184 current = prototype; 1175 current = prototype;
1185 } 1176 }
1186 ASSERT(current.is_identical_to(holder)); 1177 ASSERT(current.is_identical_to(holder));
1187 1178
1188 // Log the check depth. 1179 // Log the check depth.
1189 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1180 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1190 1181
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 // The context register (rsi) has been saved in PrepareCallApiFunction and 1383 // The context register (rsi) has been saved in PrepareCallApiFunction and
1393 // could be used to pass arguments. 1384 // could be used to pass arguments.
1394 __ lea(accessor_info_arg, StackSpaceOperand(0)); 1385 __ lea(accessor_info_arg, StackSpaceOperand(0));
1395 1386
1396 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); 1387 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
1397 1388
1398 __ CallApiFunctionAndReturn(getter_address, 1389 __ CallApiFunctionAndReturn(getter_address,
1399 thunk_address, 1390 thunk_address,
1400 getter_arg, 1391 getter_arg,
1401 kStackSpace, 1392 kStackSpace,
1402 Operand(rbp, 6 * kPointerSize), 1393 6);
1403 NULL);
1404 } 1394 }
1405 1395
1406 1396
1407 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1397 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1408 // Return the constant value. 1398 // Return the constant value.
1409 __ LoadObject(rax, value); 1399 __ LoadObject(rax, value);
1410 __ ret(0); 1400 __ ret(0);
1411 } 1401 }
1412 1402
1413 1403
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
2511 2501
2512 // Check that the maps haven't changed and find a Holder as a side effect. 2502 // 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, 2503 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
2514 name, depth, &miss); 2504 name, depth, &miss);
2515 2505
2516 // Move the return address on top of the stack. 2506 // Move the return address on top of the stack.
2517 __ movq(rax, 2507 __ movq(rax,
2518 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); 2508 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize));
2519 __ movq(StackOperandForReturnAddress(0), rax); 2509 __ movq(StackOperandForReturnAddress(0), rax);
2520 2510
2521 GenerateFastApiCall(masm(), optimization, argc, false); 2511 GenerateFastApiCall(masm(), optimization, argc);
2522 2512
2523 __ bind(&miss); 2513 __ bind(&miss);
2524 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2514 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2525 2515
2526 __ bind(&miss_before_stack_reserved); 2516 __ bind(&miss_before_stack_reserved);
2527 GenerateMissBranch(); 2517 GenerateMissBranch();
2528 2518
2529 // Return the generated code. 2519 // Return the generated code.
2530 return GetCode(function); 2520 return GetCode(function);
2531 } 2521 }
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
3172 // ----------------------------------- 3162 // -----------------------------------
3173 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3163 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3174 } 3164 }
3175 3165
3176 3166
3177 #undef __ 3167 #undef __
3178 3168
3179 } } // namespace v8::internal 3169 } } // namespace v8::internal
3180 3170
3181 #endif // V8_TARGET_ARCH_X64 3171 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/cctest/test-accessors.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698