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

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

Issue 21123008: Introduce StackArgumentsAccessor class for X64 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed nits Created 7 years, 4 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/ic-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 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 // These arguments are set by CheckPrototypes and GenerateFastApiCall. 407 // These arguments are set by CheckPrototypes and GenerateFastApiCall.
408 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { 408 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
409 // ----------- S t a t e ------------- 409 // ----------- S t a t e -------------
410 // -- rsp[0] : return address 410 // -- rsp[0] : return address
411 // -- rsp[8] : last argument in the internal frame of the caller 411 // -- rsp[8] : last argument in the internal frame of the caller
412 // ----------------------------------- 412 // -----------------------------------
413 __ movq(scratch, StackOperandForReturnAddress(0)); 413 __ movq(scratch, StackOperandForReturnAddress(0));
414 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 414 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
415 __ movq(StackOperandForReturnAddress(0), scratch); 415 __ movq(StackOperandForReturnAddress(0), scratch);
416 __ Move(scratch, Smi::FromInt(0)); 416 __ Move(scratch, Smi::FromInt(0));
417 for (int i = 1; i <= kFastApiCallArguments; i++) { 417 StackArgumentsAccessor args(rsp, kFastApiCallArguments,
418 __ movq(Operand(rsp, i * kPointerSize), scratch); 418 ARGUMENTS_DONT_CONTAIN_RECEIVER);
419 for (int i = 0; i < kFastApiCallArguments; i++) {
420 __ movq(args.GetArgumentOperand(i), scratch);
419 } 421 }
420 } 422 }
421 423
422 424
423 // Undoes the effects of ReserveSpaceForFastApiCall. 425 // Undoes the effects of ReserveSpaceForFastApiCall.
424 static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { 426 static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
425 // ----------- S t a t e ------------- 427 // ----------- S t a t e -------------
426 // -- rsp[0] : return address. 428 // -- rsp[0] : return address.
427 // -- rsp[8] : last fast api call extra argument. 429 // -- rsp[8] : last fast api call extra argument.
428 // -- ... 430 // -- ...
(...skipping 28 matching lines...) Expand all
457 // -- rsp[56] : last argument 459 // -- rsp[56] : last argument
458 // -- ... 460 // -- ...
459 // -- rsp[(argc + 6) * 8] : first argument 461 // -- rsp[(argc + 6) * 8] : first argument
460 // -- rsp[(argc + 7) * 8] : receiver 462 // -- rsp[(argc + 7) * 8] : receiver
461 // ----------------------------------- 463 // -----------------------------------
462 // Get the function and setup the context. 464 // Get the function and setup the context.
463 Handle<JSFunction> function = optimization.constant_function(); 465 Handle<JSFunction> function = optimization.constant_function();
464 __ LoadHeapObject(rdi, function); 466 __ LoadHeapObject(rdi, function);
465 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 467 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
466 468
469 int api_call_argc = argc + kFastApiCallArguments;
470 StackArgumentsAccessor args(rsp, api_call_argc);
471
467 // Pass the additional arguments. 472 // Pass the additional arguments.
468 __ movq(Operand(rsp, 2 * kPointerSize), rdi); 473 __ movq(args.GetArgumentOperand(api_call_argc - 1), rdi);
469 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 474 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
470 Handle<Object> call_data(api_call_info->data(), masm->isolate()); 475 Handle<Object> call_data(api_call_info->data(), masm->isolate());
471 if (masm->isolate()->heap()->InNewSpace(*call_data)) { 476 if (masm->isolate()->heap()->InNewSpace(*call_data)) {
472 __ Move(rcx, api_call_info); 477 __ Move(rcx, api_call_info);
473 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); 478 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
474 __ movq(Operand(rsp, 3 * kPointerSize), rbx); 479 __ movq(args.GetArgumentOperand(api_call_argc - 2), rbx);
475 } else { 480 } else {
476 __ Move(Operand(rsp, 3 * kPointerSize), call_data); 481 __ Move(args.GetArgumentOperand(api_call_argc - 2), call_data);
477 } 482 }
478 __ movq(kScratchRegister, 483 __ movq(kScratchRegister,
479 ExternalReference::isolate_address(masm->isolate())); 484 ExternalReference::isolate_address(masm->isolate()));
480 __ movq(Operand(rsp, 4 * kPointerSize), kScratchRegister); 485 __ movq(args.GetArgumentOperand(api_call_argc - 3), kScratchRegister);
481 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 486 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
482 __ movq(Operand(rsp, 5 * kPointerSize), kScratchRegister); 487 __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
483 __ movq(Operand(rsp, 6 * kPointerSize), kScratchRegister); 488 __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister);
484 489
485 // Prepare arguments. 490 // Prepare arguments.
486 STATIC_ASSERT(kFastApiCallArguments == 6); 491 STATIC_ASSERT(kFastApiCallArguments == 6);
487 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); 492 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize));
488 493
489 // Function address is a foreign pointer outside V8's heap. 494 // Function address is a foreign pointer outside V8's heap.
490 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 495 Address function_address = v8::ToCData<Address>(api_call_info->callback());
491 bool returns_handle = 496 bool returns_handle =
492 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); 497 !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
493 498
(...skipping 25 matching lines...) Expand all
519 // v8::InvocationCallback's argument. 524 // v8::InvocationCallback's argument.
520 __ lea(arguments_arg, StackSpaceOperand(0)); 525 __ lea(arguments_arg, StackSpaceOperand(0));
521 526
522 Address thunk_address = returns_handle 527 Address thunk_address = returns_handle
523 ? FUNCTION_ADDR(&InvokeInvocationCallback) 528 ? FUNCTION_ADDR(&InvokeInvocationCallback)
524 : FUNCTION_ADDR(&InvokeFunctionCallback); 529 : FUNCTION_ADDR(&InvokeFunctionCallback);
525 530
526 __ CallApiFunctionAndReturn(function_address, 531 __ CallApiFunctionAndReturn(function_address,
527 thunk_address, 532 thunk_address,
528 callback_arg, 533 callback_arg,
529 argc + kFastApiCallArguments + 1, 534 api_call_argc + 1,
530 returns_handle, 535 returns_handle,
531 kFastApiCallArguments + 1); 536 kFastApiCallArguments + 1);
532 } 537 }
533 538
534 539
535 class CallInterceptorCompiler BASE_EMBEDDED { 540 class CallInterceptorCompiler BASE_EMBEDDED {
536 public: 541 public:
537 CallInterceptorCompiler(StubCompiler* stub_compiler, 542 CallInterceptorCompiler(StubCompiler* stub_compiler,
538 const ParameterCount& arguments, 543 const ParameterCount& arguments,
539 Register name, 544 Register name,
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1073 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1069 && !scratch2.is(scratch1)); 1074 && !scratch2.is(scratch1));
1070 1075
1071 // Keep track of the current object in register reg. On the first 1076 // Keep track of the current object in register reg. On the first
1072 // iteration, reg is an alias for object_reg, on later iterations, 1077 // iteration, reg is an alias for object_reg, on later iterations,
1073 // it is an alias for holder_reg. 1078 // it is an alias for holder_reg.
1074 Register reg = object_reg; 1079 Register reg = object_reg;
1075 int depth = 0; 1080 int depth = 0;
1076 1081
1077 if (save_at_depth == depth) { 1082 if (save_at_depth == depth) {
1078 __ movq(Operand(rsp, kPointerSize), object_reg); 1083 __ movq(Operand(rsp, kPCOnStackSize), object_reg);
1079 } 1084 }
1080 1085
1081 // Check the maps in the prototype chain. 1086 // Check the maps in the prototype chain.
1082 // Traverse the prototype chain from the object and do map checks. 1087 // Traverse the prototype chain from the object and do map checks.
1083 Handle<JSObject> current = object; 1088 Handle<JSObject> current = object;
1084 while (!current.is_identical_to(holder)) { 1089 while (!current.is_identical_to(holder)) {
1085 ++depth; 1090 ++depth;
1086 1091
1087 // Only global objects and objects that do not require access 1092 // Only global objects and objects that do not require access
1088 // checks are allowed in stubs. 1093 // checks are allowed in stubs.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 // The prototype is in new space; we cannot store a reference to it 1133 // The prototype is in new space; we cannot store a reference to it
1129 // in the code. Load it from the map. 1134 // in the code. Load it from the map.
1130 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1135 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1131 } else { 1136 } else {
1132 // The prototype is in old space; load it directly. 1137 // The prototype is in old space; load it directly.
1133 __ Move(reg, prototype); 1138 __ Move(reg, prototype);
1134 } 1139 }
1135 } 1140 }
1136 1141
1137 if (save_at_depth == depth) { 1142 if (save_at_depth == depth) {
1138 __ movq(Operand(rsp, kPointerSize), reg); 1143 __ movq(Operand(rsp, kPCOnStackSize), reg);
1139 } 1144 }
1140 1145
1141 // Go to the next object in the prototype chain. 1146 // Go to the next object in the prototype chain.
1142 current = prototype; 1147 current = prototype;
1143 } 1148 }
1144 ASSERT(current.is_identical_to(holder)); 1149 ASSERT(current.is_identical_to(holder));
1145 1150
1146 // Log the check depth. 1151 // Log the check depth.
1147 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1152 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1148 1153
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 } 1468 }
1464 } 1469 }
1465 1470
1466 1471
1467 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, 1472 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
1468 Handle<JSObject> holder, 1473 Handle<JSObject> holder,
1469 Handle<Name> name, 1474 Handle<Name> name,
1470 Label* miss) { 1475 Label* miss) {
1471 ASSERT(holder->IsGlobalObject()); 1476 ASSERT(holder->IsGlobalObject());
1472 1477
1473 // Get the number of arguments. 1478 StackArgumentsAccessor args(rsp, arguments());
1474 const int argc = arguments().immediate(); 1479 __ movq(rdx, args.GetReceiverOperand());
1475
1476 // Get the receiver from the stack.
1477 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1478 1480
1479 1481
1480 // Check that the maps haven't changed. 1482 // Check that the maps haven't changed.
1481 __ JumpIfSmi(rdx, miss); 1483 __ JumpIfSmi(rdx, miss);
1482 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, miss); 1484 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, miss);
1483 } 1485 }
1484 1486
1485 1487
1486 void CallStubCompiler::GenerateLoadFunctionFromCell( 1488 void CallStubCompiler::GenerateLoadFunctionFromCell(
1487 Handle<Cell> cell, 1489 Handle<Cell> cell,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1531 // rsp[8] : argument argc 1533 // rsp[8] : argument argc
1532 // rsp[16] : argument argc - 1 1534 // rsp[16] : argument argc - 1
1533 // ... 1535 // ...
1534 // rsp[argc * 8] : argument 1 1536 // rsp[argc * 8] : argument 1
1535 // rsp[(argc + 1) * 8] : argument 0 = receiver 1537 // rsp[(argc + 1) * 8] : argument 0 = receiver
1536 // ----------------------------------- 1538 // -----------------------------------
1537 Label miss; 1539 Label miss;
1538 1540
1539 GenerateNameCheck(name, &miss); 1541 GenerateNameCheck(name, &miss);
1540 1542
1541 // Get the receiver from the stack. 1543 StackArgumentsAccessor args(rsp, arguments());
1542 const int argc = arguments().immediate(); 1544 __ movq(rdx, args.GetReceiverOperand());
1543 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1544 1545
1545 // Check that the receiver isn't a smi. 1546 // Check that the receiver isn't a smi.
1546 __ JumpIfSmi(rdx, &miss); 1547 __ JumpIfSmi(rdx, &miss);
1547 1548
1548 // Do the right check and compute the holder register. 1549 // Do the right check and compute the holder register.
1549 Register reg = CheckPrototypes(object, rdx, holder, rbx, rax, rdi, 1550 Register reg = CheckPrototypes(object, rdx, holder, rbx, rax, rdi,
1550 name, &miss); 1551 name, &miss);
1551 1552
1552 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), 1553 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder),
1553 index.translate(holder), Representation::Tagged()); 1554 index.translate(holder), Representation::Tagged());
1554 1555
1555 // Check that the function really is a function. 1556 // Check that the function really is a function.
1556 __ JumpIfSmi(rdi, &miss); 1557 __ JumpIfSmi(rdi, &miss);
1557 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); 1558 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx);
1558 __ j(not_equal, &miss); 1559 __ j(not_equal, &miss);
1559 1560
1560 // Patch the receiver on the stack with the global proxy if 1561 // Patch the receiver on the stack with the global proxy if
1561 // necessary. 1562 // necessary.
1562 if (object->IsGlobalObject()) { 1563 if (object->IsGlobalObject()) {
1563 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 1564 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
1564 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 1565 __ movq(args.GetReceiverOperand(), rdx);
1565 } 1566 }
1566 1567
1567 // Invoke the function. 1568 // Invoke the function.
1568 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 1569 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1569 ? CALL_AS_FUNCTION 1570 ? CALL_AS_FUNCTION
1570 : CALL_AS_METHOD; 1571 : CALL_AS_METHOD;
1571 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 1572 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
1572 NullCallWrapper(), call_kind); 1573 NullCallWrapper(), call_kind);
1573 1574
1574 // Handle call cache miss. 1575 // Handle call cache miss.
1575 __ bind(&miss); 1576 __ bind(&miss);
1576 GenerateMissBranch(); 1577 GenerateMissBranch();
1577 1578
1578 // Return the generated code. 1579 // Return the generated code.
1579 return GetCode(Code::FIELD, name); 1580 return GetCode(Code::FIELD, name);
1580 } 1581 }
1581 1582
1582 1583
1583 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1584 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1584 Handle<Object> object, 1585 Handle<Object> object,
1585 Handle<JSObject> holder, 1586 Handle<JSObject> holder,
1586 Handle<Cell> cell, 1587 Handle<Cell> cell,
1587 Handle<JSFunction> function, 1588 Handle<JSFunction> function,
1588 Handle<String> name, 1589 Handle<String> name,
1589 Code::StubType type) { 1590 Code::StubType type) {
1590 Label miss; 1591 Label miss;
1591 1592
1592 // Check that function is still array 1593 // Check that function is still array
1593 const int argc = arguments().immediate(); 1594 const int argc = arguments().immediate();
1595 StackArgumentsAccessor args(rsp, argc);
1594 GenerateNameCheck(name, &miss); 1596 GenerateNameCheck(name, &miss);
1595 1597
1596 if (cell.is_null()) { 1598 if (cell.is_null()) {
1597 // Get the receiver from the stack. 1599 __ movq(rdx, args.GetReceiverOperand());
1598 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1599 1600
1600 // Check that the receiver isn't a smi. 1601 // Check that the receiver isn't a smi.
1601 __ JumpIfSmi(rdx, &miss); 1602 __ JumpIfSmi(rdx, &miss);
1602 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1603 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
1603 name, &miss); 1604 name, &miss);
1604 } else { 1605 } else {
1605 ASSERT(cell->value() == *function); 1606 ASSERT(cell->value() == *function);
1606 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1607 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1607 &miss); 1608 &miss);
1608 GenerateLoadFunctionFromCell(cell, function, &miss); 1609 GenerateLoadFunctionFromCell(cell, function, &miss);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 // -- ... 1641 // -- ...
1641 // -- rsp[(argc + 1) * 8] : receiver 1642 // -- rsp[(argc + 1) * 8] : receiver
1642 // ----------------------------------- 1643 // -----------------------------------
1643 1644
1644 // If object is not an array, bail out to regular call. 1645 // If object is not an array, bail out to regular call.
1645 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); 1646 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null();
1646 1647
1647 Label miss; 1648 Label miss;
1648 GenerateNameCheck(name, &miss); 1649 GenerateNameCheck(name, &miss);
1649 1650
1650 // Get the receiver from the stack.
1651 const int argc = arguments().immediate(); 1651 const int argc = arguments().immediate();
1652 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1652 StackArgumentsAccessor args(rsp, argc);
1653 __ movq(rdx, args.GetReceiverOperand());
1653 1654
1654 // Check that the receiver isn't a smi. 1655 // Check that the receiver isn't a smi.
1655 __ JumpIfSmi(rdx, &miss); 1656 __ JumpIfSmi(rdx, &miss);
1656 1657
1657 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1658 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
1658 name, &miss); 1659 name, &miss);
1659 1660
1660 if (argc == 0) { 1661 if (argc == 0) {
1661 // Noop, return the length. 1662 // Noop, return the length.
1662 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); 1663 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset));
(...skipping 18 matching lines...) Expand all
1681 __ addl(rax, Immediate(argc)); 1682 __ addl(rax, Immediate(argc));
1682 1683
1683 // Get the elements' length into rcx. 1684 // Get the elements' length into rcx.
1684 __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); 1685 __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
1685 1686
1686 // Check if we could survive without allocation. 1687 // Check if we could survive without allocation.
1687 __ cmpl(rax, rcx); 1688 __ cmpl(rax, rcx);
1688 __ j(greater, &attempt_to_grow_elements); 1689 __ j(greater, &attempt_to_grow_elements);
1689 1690
1690 // Check if value is a smi. 1691 // Check if value is a smi.
1691 __ movq(rcx, Operand(rsp, argc * kPointerSize)); 1692 __ movq(rcx, args.GetArgumentOperand(1));
1692 __ JumpIfNotSmi(rcx, &with_write_barrier); 1693 __ JumpIfNotSmi(rcx, &with_write_barrier);
1693 1694
1694 // Save new length. 1695 // Save new length.
1695 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1696 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1696 1697
1697 // Store the value. 1698 // Store the value.
1698 __ movq(FieldOperand(rdi, 1699 __ movq(FieldOperand(rdi,
1699 rax, 1700 rax,
1700 times_pointer_size, 1701 times_pointer_size,
1701 FixedArray::kHeaderSize - argc * kPointerSize), 1702 FixedArray::kHeaderSize - argc * kPointerSize),
(...skipping 14 matching lines...) Expand all
1716 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue); 1717 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue);
1717 __ addl(rax, Immediate(argc)); 1718 __ addl(rax, Immediate(argc));
1718 1719
1719 // Get the elements' length into rcx. 1720 // Get the elements' length into rcx.
1720 __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); 1721 __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
1721 1722
1722 // Check if we could survive without allocation. 1723 // Check if we could survive without allocation.
1723 __ cmpl(rax, rcx); 1724 __ cmpl(rax, rcx);
1724 __ j(greater, &call_builtin); 1725 __ j(greater, &call_builtin);
1725 1726
1726 __ movq(rcx, Operand(rsp, argc * kPointerSize)); 1727 __ movq(rcx, args.GetArgumentOperand(1));
1727 __ StoreNumberToDoubleElements( 1728 __ StoreNumberToDoubleElements(
1728 rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize); 1729 rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize);
1729 1730
1730 // Save new length. 1731 // Save new length.
1731 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1732 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1732 __ Integer32ToSmi(rax, rax); // Return new length as smi. 1733 __ Integer32ToSmi(rax, rax); // Return new length as smi.
1733 __ ret((argc + 1) * kPointerSize); 1734 __ ret((argc + 1) * kPointerSize);
1734 1735
1735 __ bind(&with_write_barrier); 1736 __ bind(&with_write_barrier);
1736 1737
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 OMIT_SMI_CHECK); 1794 OMIT_SMI_CHECK);
1794 1795
1795 __ Integer32ToSmi(rax, rax); // Return new length as smi. 1796 __ Integer32ToSmi(rax, rax); // Return new length as smi.
1796 __ ret((argc + 1) * kPointerSize); 1797 __ ret((argc + 1) * kPointerSize);
1797 1798
1798 __ bind(&attempt_to_grow_elements); 1799 __ bind(&attempt_to_grow_elements);
1799 if (!FLAG_inline_new) { 1800 if (!FLAG_inline_new) {
1800 __ jmp(&call_builtin); 1801 __ jmp(&call_builtin);
1801 } 1802 }
1802 1803
1803 __ movq(rbx, Operand(rsp, argc * kPointerSize)); 1804 __ movq(rbx, args.GetArgumentOperand(1));
1804 // Growing elements that are SMI-only requires special handling in case 1805 // Growing elements that are SMI-only requires special handling in case
1805 // the new element is non-Smi. For now, delegate to the builtin. 1806 // the new element is non-Smi. For now, delegate to the builtin.
1806 Label no_fast_elements_check; 1807 Label no_fast_elements_check;
1807 __ JumpIfSmi(rbx, &no_fast_elements_check); 1808 __ JumpIfSmi(rbx, &no_fast_elements_check);
1808 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); 1809 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
1809 __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar); 1810 __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar);
1810 __ bind(&no_fast_elements_check); 1811 __ bind(&no_fast_elements_check);
1811 1812
1812 ExternalReference new_space_allocation_top = 1813 ExternalReference new_space_allocation_top =
1813 ExternalReference::new_space_allocation_top_address(isolate()); 1814 ExternalReference::new_space_allocation_top_address(isolate());
(...skipping 28 matching lines...) Expand all
1842 } 1843 }
1843 1844
1844 // We know the elements array is in new space so we don't need the 1845 // We know the elements array is in new space so we don't need the
1845 // remembered set, but we just pushed a value onto it so we may have to 1846 // remembered set, but we just pushed a value onto it so we may have to
1846 // tell the incremental marker to rescan the object that we just grew. We 1847 // tell the incremental marker to rescan the object that we just grew. We
1847 // don't need to worry about the holes because they are in old space and 1848 // don't need to worry about the holes because they are in old space and
1848 // already marked black. 1849 // already marked black.
1849 __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET); 1850 __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
1850 1851
1851 // Restore receiver to rdx as finish sequence assumes it's here. 1852 // Restore receiver to rdx as finish sequence assumes it's here.
1852 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1853 __ movq(rdx, args.GetReceiverOperand());
1853 1854
1854 // Increment element's and array's sizes. 1855 // Increment element's and array's sizes.
1855 __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset), 1856 __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset),
1856 Smi::FromInt(kAllocationDelta)); 1857 Smi::FromInt(kAllocationDelta));
1857 1858
1858 // Make new length a smi before returning it. 1859 // Make new length a smi before returning it.
1859 __ Integer32ToSmi(rax, rax); 1860 __ Integer32ToSmi(rax, rax);
1860 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1861 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1861 1862
1862 __ ret((argc + 1) * kPointerSize); 1863 __ ret((argc + 1) * kPointerSize);
(...skipping 28 matching lines...) Expand all
1891 // -- ... 1892 // -- ...
1892 // -- rsp[(argc + 1) * 8] : receiver 1893 // -- rsp[(argc + 1) * 8] : receiver
1893 // ----------------------------------- 1894 // -----------------------------------
1894 1895
1895 // If object is not an array, bail out to regular call. 1896 // If object is not an array, bail out to regular call.
1896 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); 1897 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null();
1897 1898
1898 Label miss, return_undefined, call_builtin; 1899 Label miss, return_undefined, call_builtin;
1899 GenerateNameCheck(name, &miss); 1900 GenerateNameCheck(name, &miss);
1900 1901
1901 // Get the receiver from the stack.
1902 const int argc = arguments().immediate(); 1902 const int argc = arguments().immediate();
1903 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1903 StackArgumentsAccessor args(rsp, argc);
1904 __ movq(rdx, args.GetReceiverOperand());
1904 1905
1905 // Check that the receiver isn't a smi. 1906 // Check that the receiver isn't a smi.
1906 __ JumpIfSmi(rdx, &miss); 1907 __ JumpIfSmi(rdx, &miss);
1907 1908
1908 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1909 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
1909 name, &miss); 1910 name, &miss);
1910 1911
1911 // Get the elements array of the object. 1912 // Get the elements array of the object.
1912 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); 1913 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset));
1913 1914
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1971 // -- rsp[0] : return address 1972 // -- rsp[0] : return address
1972 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1973 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1973 // -- ... 1974 // -- ...
1974 // -- rsp[(argc + 1) * 8] : receiver 1975 // -- rsp[(argc + 1) * 8] : receiver
1975 // ----------------------------------- 1976 // -----------------------------------
1976 1977
1977 // If object is not a string, bail out to regular call. 1978 // If object is not a string, bail out to regular call.
1978 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1979 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
1979 1980
1980 const int argc = arguments().immediate(); 1981 const int argc = arguments().immediate();
1982 StackArgumentsAccessor args(rsp, argc);
1981 1983
1982 Label miss; 1984 Label miss;
1983 Label name_miss; 1985 Label name_miss;
1984 Label index_out_of_range; 1986 Label index_out_of_range;
1985 Label* index_out_of_range_label = &index_out_of_range; 1987 Label* index_out_of_range_label = &index_out_of_range;
1986 if (kind_ == Code::CALL_IC && 1988 if (kind_ == Code::CALL_IC &&
1987 (CallICBase::StringStubState::decode(extra_state_) == 1989 (CallICBase::StringStubState::decode(extra_state_) ==
1988 DEFAULT_STRING_STUB)) { 1990 DEFAULT_STRING_STUB)) {
1989 index_out_of_range_label = &miss; 1991 index_out_of_range_label = &miss;
1990 } 1992 }
1991 GenerateNameCheck(name, &name_miss); 1993 GenerateNameCheck(name, &name_miss);
1992 1994
1993 // Check that the maps starting from the prototype haven't changed. 1995 // Check that the maps starting from the prototype haven't changed.
1994 GenerateDirectLoadGlobalFunctionPrototype(masm(), 1996 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1995 Context::STRING_FUNCTION_INDEX, 1997 Context::STRING_FUNCTION_INDEX,
1996 rax, 1998 rax,
1997 &miss); 1999 &miss);
1998 ASSERT(!object.is_identical_to(holder)); 2000 ASSERT(!object.is_identical_to(holder));
1999 CheckPrototypes( 2001 CheckPrototypes(
2000 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2002 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2001 rax, holder, rbx, rdx, rdi, name, &miss); 2003 rax, holder, rbx, rdx, rdi, name, &miss);
2002 2004
2003 Register receiver = rbx; 2005 Register receiver = rbx;
2004 Register index = rdi; 2006 Register index = rdi;
2005 Register result = rax; 2007 Register result = rax;
2006 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); 2008 __ movq(receiver, args.GetReceiverOperand());
2007 if (argc > 0) { 2009 if (argc > 0) {
2008 __ movq(index, Operand(rsp, (argc - 0) * kPointerSize)); 2010 __ movq(index, args.GetArgumentOperand(1));
2009 } else { 2011 } else {
2010 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2012 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2011 } 2013 }
2012 2014
2013 StringCharCodeAtGenerator generator(receiver, 2015 StringCharCodeAtGenerator generator(receiver,
2014 index, 2016 index,
2015 result, 2017 result,
2016 &miss, // When not a string. 2018 &miss, // When not a string.
2017 &miss, // When not a number. 2019 &miss, // When not a number.
2018 index_out_of_range_label, 2020 index_out_of_range_label,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2052 // -- rsp[0] : return address 2054 // -- rsp[0] : return address
2053 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 2055 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
2054 // -- ... 2056 // -- ...
2055 // -- rsp[(argc + 1) * 8] : receiver 2057 // -- rsp[(argc + 1) * 8] : receiver
2056 // ----------------------------------- 2058 // -----------------------------------
2057 2059
2058 // If object is not a string, bail out to regular call. 2060 // If object is not a string, bail out to regular call.
2059 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 2061 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2060 2062
2061 const int argc = arguments().immediate(); 2063 const int argc = arguments().immediate();
2064 StackArgumentsAccessor args(rsp, argc);
2065
2062 Label miss; 2066 Label miss;
2063 Label name_miss; 2067 Label name_miss;
2064 Label index_out_of_range; 2068 Label index_out_of_range;
2065 Label* index_out_of_range_label = &index_out_of_range; 2069 Label* index_out_of_range_label = &index_out_of_range;
2066 if (kind_ == Code::CALL_IC && 2070 if (kind_ == Code::CALL_IC &&
2067 (CallICBase::StringStubState::decode(extra_state_) == 2071 (CallICBase::StringStubState::decode(extra_state_) ==
2068 DEFAULT_STRING_STUB)) { 2072 DEFAULT_STRING_STUB)) {
2069 index_out_of_range_label = &miss; 2073 index_out_of_range_label = &miss;
2070 } 2074 }
2071 GenerateNameCheck(name, &name_miss); 2075 GenerateNameCheck(name, &name_miss);
2072 2076
2073 // Check that the maps starting from the prototype haven't changed. 2077 // Check that the maps starting from the prototype haven't changed.
2074 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2078 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2075 Context::STRING_FUNCTION_INDEX, 2079 Context::STRING_FUNCTION_INDEX,
2076 rax, 2080 rax,
2077 &miss); 2081 &miss);
2078 ASSERT(!object.is_identical_to(holder)); 2082 ASSERT(!object.is_identical_to(holder));
2079 CheckPrototypes( 2083 CheckPrototypes(
2080 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2084 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2081 rax, holder, rbx, rdx, rdi, name, &miss); 2085 rax, holder, rbx, rdx, rdi, name, &miss);
2082 2086
2083 Register receiver = rax; 2087 Register receiver = rax;
2084 Register index = rdi; 2088 Register index = rdi;
2085 Register scratch = rdx; 2089 Register scratch = rdx;
2086 Register result = rax; 2090 Register result = rax;
2087 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); 2091 __ movq(receiver, args.GetReceiverOperand());
2088 if (argc > 0) { 2092 if (argc > 0) {
2089 __ movq(index, Operand(rsp, (argc - 0) * kPointerSize)); 2093 __ movq(index, args.GetArgumentOperand(1));
2090 } else { 2094 } else {
2091 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2095 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2092 } 2096 }
2093 2097
2094 StringCharAtGenerator generator(receiver, 2098 StringCharAtGenerator generator(receiver,
2095 index, 2099 index,
2096 scratch, 2100 scratch,
2097 result, 2101 result,
2098 &miss, // When not a string. 2102 &miss, // When not a string.
2099 &miss, // When not a number. 2103 &miss, // When not a number.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2132 // -- rcx : function name 2136 // -- rcx : function name
2133 // -- rsp[0] : return address 2137 // -- rsp[0] : return address
2134 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 2138 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
2135 // -- ... 2139 // -- ...
2136 // -- rsp[(argc + 1) * 8] : receiver 2140 // -- rsp[(argc + 1) * 8] : receiver
2137 // ----------------------------------- 2141 // -----------------------------------
2138 2142
2139 // If the object is not a JSObject or we got an unexpected number of 2143 // If the object is not a JSObject or we got an unexpected number of
2140 // arguments, bail out to the regular call. 2144 // arguments, bail out to the regular call.
2141 const int argc = arguments().immediate(); 2145 const int argc = arguments().immediate();
2146 StackArgumentsAccessor args(rsp, argc);
2142 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2147 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2143 2148
2144 Label miss; 2149 Label miss;
2145 GenerateNameCheck(name, &miss); 2150 GenerateNameCheck(name, &miss);
2146 2151
2147 if (cell.is_null()) { 2152 if (cell.is_null()) {
2148 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2153 __ movq(rdx, args.GetArgumentOperand(argc - 1));
2149 __ JumpIfSmi(rdx, &miss); 2154 __ JumpIfSmi(rdx, &miss);
2150 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2155 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
2151 name, &miss); 2156 name, &miss);
2152 } else { 2157 } else {
2153 ASSERT(cell->value() == *function); 2158 ASSERT(cell->value() == *function);
2154 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2159 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2155 &miss); 2160 &miss);
2156 GenerateLoadFunctionFromCell(cell, function, &miss); 2161 GenerateLoadFunctionFromCell(cell, function, &miss);
2157 } 2162 }
2158 2163
2159 // Load the char code argument. 2164 // Load the char code argument.
2160 Register code = rbx; 2165 Register code = rbx;
2161 __ movq(code, Operand(rsp, 1 * kPointerSize)); 2166 __ movq(code, args.GetArgumentOperand(argc));
2162 2167
2163 // Check the code is a smi. 2168 // Check the code is a smi.
2164 Label slow; 2169 Label slow;
2165 __ JumpIfNotSmi(code, &slow); 2170 __ JumpIfNotSmi(code, &slow);
2166 2171
2167 // Convert the smi code to uint16. 2172 // Convert the smi code to uint16.
2168 __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); 2173 __ SmiAndConstant(code, code, Smi::FromInt(0xffff));
2169 2174
2170 StringCharFromCodeGenerator generator(code, rax); 2175 StringCharFromCodeGenerator generator(code, rax);
2171 generator.GenerateFast(masm()); 2176 generator.GenerateFast(masm());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2216 // -- rcx : function name 2221 // -- rcx : function name
2217 // -- rsp[0] : return address 2222 // -- rsp[0] : return address
2218 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 2223 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
2219 // -- ... 2224 // -- ...
2220 // -- rsp[(argc + 1) * 8] : receiver 2225 // -- rsp[(argc + 1) * 8] : receiver
2221 // ----------------------------------- 2226 // -----------------------------------
2222 2227
2223 // If the object is not a JSObject or we got an unexpected number of 2228 // If the object is not a JSObject or we got an unexpected number of
2224 // arguments, bail out to the regular call. 2229 // arguments, bail out to the regular call.
2225 const int argc = arguments().immediate(); 2230 const int argc = arguments().immediate();
2231 StackArgumentsAccessor args(rsp, argc);
2226 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2232 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2227 2233
2228 Label miss; 2234 Label miss;
2229 GenerateNameCheck(name, &miss); 2235 GenerateNameCheck(name, &miss);
2230 2236
2231 if (cell.is_null()) { 2237 if (cell.is_null()) {
2232 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2238 __ movq(rdx, args.GetArgumentOperand(argc - 1));
2233 __ JumpIfSmi(rdx, &miss); 2239 __ JumpIfSmi(rdx, &miss);
2234 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2240 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
2235 name, &miss); 2241 name, &miss);
2236 } else { 2242 } else {
2237 ASSERT(cell->value() == *function); 2243 ASSERT(cell->value() == *function);
2238 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2244 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2239 &miss); 2245 &miss);
2240 GenerateLoadFunctionFromCell(cell, function, &miss); 2246 GenerateLoadFunctionFromCell(cell, function, &miss);
2241 } 2247 }
2242 // Load the (only) argument into rax. 2248 // Load the (only) argument into rax.
2243 __ movq(rax, Operand(rsp, 1 * kPointerSize)); 2249 __ movq(rax, args.GetArgumentOperand(argc));
2244 2250
2245 // Check if the argument is a smi. 2251 // Check if the argument is a smi.
2246 Label not_smi; 2252 Label not_smi;
2247 STATIC_ASSERT(kSmiTag == 0); 2253 STATIC_ASSERT(kSmiTag == 0);
2248 __ JumpIfNotSmi(rax, &not_smi); 2254 __ JumpIfNotSmi(rax, &not_smi);
2249 __ SmiToInteger32(rax, rax); 2255 __ SmiToInteger32(rax, rax);
2250 2256
2251 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0 2257 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
2252 // otherwise. 2258 // otherwise.
2253 __ movl(rbx, rax); 2259 __ movl(rbx, rax);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2324 if (object->IsGlobalObject()) return Handle<Code>::null(); 2330 if (object->IsGlobalObject()) return Handle<Code>::null();
2325 if (!cell.is_null()) return Handle<Code>::null(); 2331 if (!cell.is_null()) return Handle<Code>::null();
2326 if (!object->IsJSObject()) return Handle<Code>::null(); 2332 if (!object->IsJSObject()) return Handle<Code>::null();
2327 int depth = optimization.GetPrototypeDepthOfExpectedType( 2333 int depth = optimization.GetPrototypeDepthOfExpectedType(
2328 Handle<JSObject>::cast(object), holder); 2334 Handle<JSObject>::cast(object), holder);
2329 if (depth == kInvalidProtoDepth) return Handle<Code>::null(); 2335 if (depth == kInvalidProtoDepth) return Handle<Code>::null();
2330 2336
2331 Label miss, miss_before_stack_reserved; 2337 Label miss, miss_before_stack_reserved;
2332 GenerateNameCheck(name, &miss_before_stack_reserved); 2338 GenerateNameCheck(name, &miss_before_stack_reserved);
2333 2339
2334 // Get the receiver from the stack.
2335 const int argc = arguments().immediate(); 2340 const int argc = arguments().immediate();
2336 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2341 StackArgumentsAccessor args(rsp, argc);
2342 __ movq(rdx, args.GetReceiverOperand());
2337 2343
2338 // Check that the receiver isn't a smi. 2344 // Check that the receiver isn't a smi.
2339 __ JumpIfSmi(rdx, &miss_before_stack_reserved); 2345 __ JumpIfSmi(rdx, &miss_before_stack_reserved);
2340 2346
2341 Counters* counters = isolate()->counters(); 2347 Counters* counters = isolate()->counters();
2342 __ IncrementCounter(counters->call_const(), 1); 2348 __ IncrementCounter(counters->call_const(), 1);
2343 __ IncrementCounter(counters->call_const_fast_api(), 1); 2349 __ IncrementCounter(counters->call_const_fast_api(), 1);
2344 2350
2345 // Allocate space for v8::Arguments implicit values. Must be initialized 2351 // Allocate space for v8::Arguments implicit values. Must be initialized
2346 // before calling any runtime function. 2352 // before calling any runtime function.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2378 // rsp[0] : return address 2384 // rsp[0] : return address
2379 // rsp[8] : argument argc 2385 // rsp[8] : argument argc
2380 // rsp[16] : argument argc - 1 2386 // rsp[16] : argument argc - 1
2381 // ... 2387 // ...
2382 // rsp[argc * 8] : argument 1 2388 // rsp[argc * 8] : argument 1
2383 // rsp[(argc + 1) * 8] : argument 0 = receiver 2389 // rsp[(argc + 1) * 8] : argument 0 = receiver
2384 // ----------------------------------- 2390 // -----------------------------------
2385 Label miss; 2391 Label miss;
2386 GenerateNameCheck(name, &miss); 2392 GenerateNameCheck(name, &miss);
2387 2393
2388 // Get the receiver from the stack. 2394 StackArgumentsAccessor args(rsp, arguments());
2389 const int argc = arguments().immediate(); 2395 __ movq(rdx, args.GetReceiverOperand());
2390 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2391 2396
2392 // Check that the receiver isn't a smi. 2397 // Check that the receiver isn't a smi.
2393 if (check != NUMBER_CHECK) { 2398 if (check != NUMBER_CHECK) {
2394 __ JumpIfSmi(rdx, &miss); 2399 __ JumpIfSmi(rdx, &miss);
2395 } 2400 }
2396 2401
2397 // Make sure that it's okay not to patch the on stack receiver 2402 // Make sure that it's okay not to patch the on stack receiver
2398 // unless we're doing a receiver map check. 2403 // unless we're doing a receiver map check.
2399 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2404 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2400 2405
2401 Counters* counters = isolate()->counters(); 2406 Counters* counters = isolate()->counters();
2402 switch (check) { 2407 switch (check) {
2403 case RECEIVER_MAP_CHECK: 2408 case RECEIVER_MAP_CHECK:
2404 __ IncrementCounter(counters->call_const(), 1); 2409 __ IncrementCounter(counters->call_const(), 1);
2405 2410
2406 // Check that the maps haven't changed. 2411 // Check that the maps haven't changed.
2407 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, 2412 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax,
2408 rdi, name, &miss); 2413 rdi, name, &miss);
2409 2414
2410 // Patch the receiver on the stack with the global proxy if 2415 // Patch the receiver on the stack with the global proxy if
2411 // necessary. 2416 // necessary.
2412 if (object->IsGlobalObject()) { 2417 if (object->IsGlobalObject()) {
2413 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2418 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2414 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2419 __ movq(args.GetReceiverOperand(), rdx);
2415 } 2420 }
2416 break; 2421 break;
2417 2422
2418 case STRING_CHECK: 2423 case STRING_CHECK:
2419 // Check that the object is a string. 2424 // Check that the object is a string.
2420 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); 2425 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
2421 __ j(above_equal, &miss); 2426 __ j(above_equal, &miss);
2422 // Check that the maps starting from the prototype haven't changed. 2427 // Check that the maps starting from the prototype haven't changed.
2423 GenerateDirectLoadGlobalFunctionPrototype( 2428 GenerateDirectLoadGlobalFunctionPrototype(
2424 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss); 2429 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2524 // rsp[0] : return address 2529 // rsp[0] : return address
2525 // rsp[8] : argument argc 2530 // rsp[8] : argument argc
2526 // rsp[16] : argument argc - 1 2531 // rsp[16] : argument argc - 1
2527 // ... 2532 // ...
2528 // rsp[argc * 8] : argument 1 2533 // rsp[argc * 8] : argument 1
2529 // rsp[(argc + 1) * 8] : argument 0 = receiver 2534 // rsp[(argc + 1) * 8] : argument 0 = receiver
2530 // ----------------------------------- 2535 // -----------------------------------
2531 Label miss; 2536 Label miss;
2532 GenerateNameCheck(name, &miss); 2537 GenerateNameCheck(name, &miss);
2533 2538
2534 // Get the number of arguments.
2535 const int argc = arguments().immediate();
2536 2539
2537 LookupResult lookup(isolate()); 2540 LookupResult lookup(isolate());
2538 LookupPostInterceptor(holder, name, &lookup); 2541 LookupPostInterceptor(holder, name, &lookup);
2539 2542
2540 // Get the receiver from the stack. 2543 // Get the receiver from the stack.
2541 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2544 StackArgumentsAccessor args(rsp, arguments());
2545 __ movq(rdx, args.GetReceiverOperand());
2542 2546
2543 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); 2547 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_);
2544 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, 2548 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
2545 &miss); 2549 &miss);
2546 2550
2547 // Restore receiver. 2551 // Restore receiver.
2548 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2552 __ movq(rdx, args.GetReceiverOperand());
2549 2553
2550 // Check that the function really is a function. 2554 // Check that the function really is a function.
2551 __ JumpIfSmi(rax, &miss); 2555 __ JumpIfSmi(rax, &miss);
2552 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 2556 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
2553 __ j(not_equal, &miss); 2557 __ j(not_equal, &miss);
2554 2558
2555 // Patch the receiver on the stack with the global proxy if 2559 // Patch the receiver on the stack with the global proxy if
2556 // necessary. 2560 // necessary.
2557 if (object->IsGlobalObject()) { 2561 if (object->IsGlobalObject()) {
2558 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2562 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2559 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2563 __ movq(args.GetReceiverOperand(), rdx);
2560 } 2564 }
2561 2565
2562 // Invoke the function. 2566 // Invoke the function.
2563 __ movq(rdi, rax); 2567 __ movq(rdi, rax);
2564 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2568 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2565 ? CALL_AS_FUNCTION 2569 ? CALL_AS_FUNCTION
2566 : CALL_AS_METHOD; 2570 : CALL_AS_METHOD;
2567 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 2571 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2568 NullCallWrapper(), call_kind); 2572 NullCallWrapper(), call_kind);
2569 2573
(...skipping 26 matching lines...) Expand all
2596 Handle<Code> code = CompileCustomCall( 2600 Handle<Code> code = CompileCustomCall(
2597 object, holder, cell, function, Handle<String>::cast(name), 2601 object, holder, cell, function, Handle<String>::cast(name),
2598 Code::NORMAL); 2602 Code::NORMAL);
2599 // A null handle means bail out to the regular compiler code below. 2603 // A null handle means bail out to the regular compiler code below.
2600 if (!code.is_null()) return code; 2604 if (!code.is_null()) return code;
2601 } 2605 }
2602 2606
2603 Label miss; 2607 Label miss;
2604 GenerateNameCheck(name, &miss); 2608 GenerateNameCheck(name, &miss);
2605 2609
2606 // Get the number of arguments. 2610 StackArgumentsAccessor args(rsp, arguments());
2607 const int argc = arguments().immediate();
2608 GenerateGlobalReceiverCheck(object, holder, name, &miss); 2611 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2609 GenerateLoadFunctionFromCell(cell, function, &miss); 2612 GenerateLoadFunctionFromCell(cell, function, &miss);
2610 2613
2611 // Patch the receiver on the stack with the global proxy. 2614 // Patch the receiver on the stack with the global proxy.
2612 if (object->IsGlobalObject()) { 2615 if (object->IsGlobalObject()) {
2613 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2616 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2614 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2617 __ movq(args.GetReceiverOperand(), rdx);
2615 } 2618 }
2616 2619
2617 // Set up the context (function already in rdi). 2620 // Set up the context (function already in rdi).
2618 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 2621 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2619 2622
2620 // Jump to the cached code (tail call). 2623 // Jump to the cached code (tail call).
2621 Counters* counters = isolate()->counters(); 2624 Counters* counters = isolate()->counters();
2622 __ IncrementCounter(counters->call_global_inline(), 1); 2625 __ IncrementCounter(counters->call_global_inline(), 1);
2623 ParameterCount expected(function->shared()->formal_parameter_count()); 2626 ParameterCount expected(function->shared()->formal_parameter_count());
2624 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2627 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
3514 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3517 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3515 } 3518 }
3516 } 3519 }
3517 3520
3518 3521
3519 #undef __ 3522 #undef __
3520 3523
3521 } } // namespace v8::internal 3524 } } // namespace v8::internal
3522 3525
3523 #endif // V8_TARGET_ARCH_X64 3526 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/ic-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698