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

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

Issue 19857006: Introduce StackOperandForArgument for X64 to access stack argument (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: One more place 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
« src/x64/builtins-x64.cc ('K') | « 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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
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, Operand(rsp, 0)); 413 __ movq(scratch, Operand(rsp, 0));
414 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 414 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
415 __ movq(Operand(rsp, 0), scratch); 415 __ movq(Operand(rsp, 0), scratch);
416 __ Move(scratch, Smi::FromInt(0)); 416 __ Move(scratch, Smi::FromInt(0));
417 for (int i = 1; i <= kFastApiCallArguments; i++) { 417 for (int i = 1; i <= kFastApiCallArguments; i++) {
418 __ movq(Operand(rsp, i * kPointerSize), scratch); 418 __ movq(Operand(rsp, kPCOnStackSize + (i - 1) * kPointerSize), scratch);
419 } 419 }
420 } 420 }
421 421
422 422
423 // Undoes the effects of ReserveSpaceForFastApiCall. 423 // Undoes the effects of ReserveSpaceForFastApiCall.
424 static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { 424 static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
425 // ----------- S t a t e ------------- 425 // ----------- S t a t e -------------
426 // -- rsp[0] : return address. 426 // -- rsp[0] : return address.
427 // -- rsp[8] : last fast api call extra argument. 427 // -- rsp[8] : last fast api call extra argument.
428 // -- ... 428 // -- ...
429 // -- rsp[kFastApiCallArguments * 8] : first fast api call extra 429 // -- rsp[kFastApiCallArguments * 8] : first fast api call extra
430 // argument. 430 // argument.
431 // -- rsp[kFastApiCallArguments * 8 + 8] : last argument in the internal 431 // -- rsp[kFastApiCallArguments * 8 + kPCOnStackSize] : last argument
432 // frame. 432 // in the internal frame.
433 // ----------------------------------- 433 // -----------------------------------
434 __ movq(scratch, Operand(rsp, 0)); 434 __ movq(scratch, Operand(rsp, 0));
435 __ movq(Operand(rsp, kFastApiCallArguments * kPointerSize), scratch); 435 __ movq(Operand(rsp, kFastApiCallArguments * kPointerSize), scratch);
436 __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments)); 436 __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments));
437 } 437 }
438 438
439 439
440 // Generates call to API function. 440 // Generates call to API function.
441 static void GenerateFastApiCall(MacroAssembler* masm, 441 static void GenerateFastApiCall(MacroAssembler* masm,
442 const CallOptimization& optimization, 442 const CallOptimization& optimization,
(...skipping 14 matching lines...) Expand all
457 // -- ... 457 // -- ...
458 // -- rsp[(argc + 6) * 8] : first argument 458 // -- rsp[(argc + 6) * 8] : first argument
459 // -- rsp[(argc + 7) * 8] : receiver 459 // -- rsp[(argc + 7) * 8] : receiver
460 // ----------------------------------- 460 // -----------------------------------
461 // Get the function and setup the context. 461 // Get the function and setup the context.
462 Handle<JSFunction> function = optimization.constant_function(); 462 Handle<JSFunction> function = optimization.constant_function();
463 __ LoadHeapObject(rdi, function); 463 __ LoadHeapObject(rdi, function);
464 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 464 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
465 465
466 // Pass the additional arguments. 466 // Pass the additional arguments.
467 __ movq(Operand(rsp, 2 * kPointerSize), rdi); 467 __ movq(Operand(rsp, kPCOnStackSize + 1 * kPointerSize), rdi);
468 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 468 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
469 Handle<Object> call_data(api_call_info->data(), masm->isolate()); 469 Handle<Object> call_data(api_call_info->data(), masm->isolate());
470 if (masm->isolate()->heap()->InNewSpace(*call_data)) { 470 if (masm->isolate()->heap()->InNewSpace(*call_data)) {
471 __ Move(rcx, api_call_info); 471 __ Move(rcx, api_call_info);
472 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); 472 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
473 __ movq(Operand(rsp, 3 * kPointerSize), rbx); 473 __ movq(Operand(rsp, kPCOnStackSize + 2 * kPointerSize), rbx);
474 } else { 474 } else {
475 __ Move(Operand(rsp, 3 * kPointerSize), call_data); 475 __ Move(Operand(rsp, kPCOnStackSize + 2 * kPointerSize), call_data);
476 } 476 }
477 __ movq(kScratchRegister, 477 __ movq(kScratchRegister,
478 ExternalReference::isolate_address(masm->isolate())); 478 ExternalReference::isolate_address(masm->isolate()));
479 __ movq(Operand(rsp, 4 * kPointerSize), kScratchRegister); 479 __ movq(Operand(rsp, kPCOnStackSize + 3 * kPointerSize), kScratchRegister);
480 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 480 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
481 __ movq(Operand(rsp, 5 * kPointerSize), kScratchRegister); 481 __ movq(Operand(rsp, kPCOnStackSize + 4 * kPointerSize), kScratchRegister);
482 __ movq(Operand(rsp, 6 * kPointerSize), kScratchRegister); 482 __ movq(Operand(rsp, kPCOnStackSize + 5 * kPointerSize), kScratchRegister);
483 483
484 // Prepare arguments. 484 // Prepare arguments.
485 STATIC_ASSERT(kFastApiCallArguments == 6); 485 STATIC_ASSERT(kFastApiCallArguments == 6);
486 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); 486 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize));
487 487
488 // Function address is a foreign pointer outside V8's heap. 488 // Function address is a foreign pointer outside V8's heap.
489 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 489 Address function_address = v8::ToCData<Address>(api_call_info->callback());
490 bool returns_handle = 490 bool returns_handle =
491 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); 491 !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
492 492
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1067 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1068 && !scratch2.is(scratch1)); 1068 && !scratch2.is(scratch1));
1069 1069
1070 // Keep track of the current object in register reg. On the first 1070 // Keep track of the current object in register reg. On the first
1071 // iteration, reg is an alias for object_reg, on later iterations, 1071 // iteration, reg is an alias for object_reg, on later iterations,
1072 // it is an alias for holder_reg. 1072 // it is an alias for holder_reg.
1073 Register reg = object_reg; 1073 Register reg = object_reg;
1074 int depth = 0; 1074 int depth = 0;
1075 1075
1076 if (save_at_depth == depth) { 1076 if (save_at_depth == depth) {
1077 __ movq(Operand(rsp, kPointerSize), object_reg); 1077 __ movq(Operand(rsp, kPCOnStackSize), object_reg);
1078 } 1078 }
1079 1079
1080 // Check the maps in the prototype chain. 1080 // Check the maps in the prototype chain.
1081 // Traverse the prototype chain from the object and do map checks. 1081 // Traverse the prototype chain from the object and do map checks.
1082 Handle<JSObject> current = object; 1082 Handle<JSObject> current = object;
1083 while (!current.is_identical_to(holder)) { 1083 while (!current.is_identical_to(holder)) {
1084 ++depth; 1084 ++depth;
1085 1085
1086 // Only global objects and objects that do not require access 1086 // Only global objects and objects that do not require access
1087 // checks are allowed in stubs. 1087 // checks are allowed in stubs.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 // The prototype is in new space; we cannot store a reference to it 1127 // The prototype is in new space; we cannot store a reference to it
1128 // in the code. Load it from the map. 1128 // in the code. Load it from the map.
1129 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1129 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1130 } else { 1130 } else {
1131 // The prototype is in old space; load it directly. 1131 // The prototype is in old space; load it directly.
1132 __ Move(reg, prototype); 1132 __ Move(reg, prototype);
1133 } 1133 }
1134 } 1134 }
1135 1135
1136 if (save_at_depth == depth) { 1136 if (save_at_depth == depth) {
1137 __ movq(Operand(rsp, kPointerSize), reg); 1137 __ movq(Operand(rsp, kPCOnStackSize), reg);
1138 } 1138 }
1139 1139
1140 // Go to the next object in the prototype chain. 1140 // Go to the next object in the prototype chain.
1141 current = prototype; 1141 current = prototype;
1142 } 1142 }
1143 ASSERT(current.is_identical_to(holder)); 1143 ASSERT(current.is_identical_to(holder));
1144 1144
1145 // Log the check depth. 1145 // Log the check depth.
1146 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1146 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1147 1147
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, 1466 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
1467 Handle<JSObject> holder, 1467 Handle<JSObject> holder,
1468 Handle<Name> name, 1468 Handle<Name> name,
1469 Label* miss) { 1469 Label* miss) {
1470 ASSERT(holder->IsGlobalObject()); 1470 ASSERT(holder->IsGlobalObject());
1471 1471
1472 // Get the number of arguments. 1472 // Get the number of arguments.
1473 const int argc = arguments().immediate(); 1473 const int argc = arguments().immediate();
1474 1474
1475 // Get the receiver from the stack. 1475 // Get the receiver from the stack.
1476 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1476 __ movq(rdx, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
1477 1477
1478 1478
1479 // Check that the maps haven't changed. 1479 // Check that the maps haven't changed.
1480 __ JumpIfSmi(rdx, miss); 1480 __ JumpIfSmi(rdx, miss);
1481 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, miss); 1481 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, miss);
1482 } 1482 }
1483 1483
1484 1484
1485 void CallStubCompiler::GenerateLoadFunctionFromCell( 1485 void CallStubCompiler::GenerateLoadFunctionFromCell(
1486 Handle<Cell> cell, 1486 Handle<Cell> cell,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 extra_state_); 1518 extra_state_);
1519 __ Jump(code, RelocInfo::CODE_TARGET); 1519 __ Jump(code, RelocInfo::CODE_TARGET);
1520 } 1520 }
1521 1521
1522 1522
1523 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1523 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1524 Handle<JSObject> holder, 1524 Handle<JSObject> holder,
1525 PropertyIndex index, 1525 PropertyIndex index,
1526 Handle<Name> name) { 1526 Handle<Name> name) {
1527 // ----------- S t a t e ------------- 1527 // ----------- S t a t e -------------
1528 // rcx : function name 1528 // rcx : function name
1529 // rsp[0] : return address 1529 // rsp[0] : return address
1530 // rsp[8] : argument argc 1530 // rsp[8] : argument argc
1531 // rsp[16] : argument argc - 1 1531 // rsp[16] : argument argc - 1
1532 // ... 1532 // ...
1533 // rsp[argc * 8] : argument 1 1533 // rsp[argc * 8] : argument 1
1534 // rsp[(argc + 1) * 8] : argument 0 = receiver 1534 // rsp[argc * 8 + kPCOnStackSize] : argument 0 = receiver
1535 // ----------------------------------- 1535 // -----------------------------------
1536 Label miss; 1536 Label miss;
1537 1537
1538 GenerateNameCheck(name, &miss); 1538 GenerateNameCheck(name, &miss);
1539 1539
1540 // Get the receiver from the stack. 1540 // Get the receiver from the stack.
1541 const int argc = arguments().immediate(); 1541 const int argc = arguments().immediate();
1542 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1542 __ movq(rdx, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
1543 1543
1544 // Check that the receiver isn't a smi. 1544 // Check that the receiver isn't a smi.
1545 __ JumpIfSmi(rdx, &miss); 1545 __ JumpIfSmi(rdx, &miss);
1546 1546
1547 // Do the right check and compute the holder register. 1547 // Do the right check and compute the holder register.
1548 Register reg = CheckPrototypes(object, rdx, holder, rbx, rax, rdi, 1548 Register reg = CheckPrototypes(object, rdx, holder, rbx, rax, rdi,
1549 name, &miss); 1549 name, &miss);
1550 1550
1551 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), 1551 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder),
1552 index.translate(holder), Representation::Tagged()); 1552 index.translate(holder), Representation::Tagged());
1553 1553
1554 // Check that the function really is a function. 1554 // Check that the function really is a function.
1555 __ JumpIfSmi(rdi, &miss); 1555 __ JumpIfSmi(rdi, &miss);
1556 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); 1556 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx);
1557 __ j(not_equal, &miss); 1557 __ j(not_equal, &miss);
1558 1558
1559 // Patch the receiver on the stack with the global proxy if 1559 // Patch the receiver on the stack with the global proxy if
1560 // necessary. 1560 // necessary.
1561 if (object->IsGlobalObject()) { 1561 if (object->IsGlobalObject()) {
1562 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 1562 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
1563 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 1563 __ movq(Operand(rsp, kPCOnStackSize + argc * kPointerSize), rdx);
1564 } 1564 }
1565 1565
1566 // Invoke the function. 1566 // Invoke the function.
1567 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 1567 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1568 ? CALL_AS_FUNCTION 1568 ? CALL_AS_FUNCTION
1569 : CALL_AS_METHOD; 1569 : CALL_AS_METHOD;
1570 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 1570 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
1571 NullCallWrapper(), call_kind); 1571 NullCallWrapper(), call_kind);
1572 1572
1573 // Handle call cache miss. 1573 // Handle call cache miss.
(...skipping 13 matching lines...) Expand all
1587 Handle<String> name, 1587 Handle<String> name,
1588 Code::StubType type) { 1588 Code::StubType type) {
1589 Label miss; 1589 Label miss;
1590 1590
1591 // Check that function is still array 1591 // Check that function is still array
1592 const int argc = arguments().immediate(); 1592 const int argc = arguments().immediate();
1593 GenerateNameCheck(name, &miss); 1593 GenerateNameCheck(name, &miss);
1594 1594
1595 if (cell.is_null()) { 1595 if (cell.is_null()) {
1596 // Get the receiver from the stack. 1596 // Get the receiver from the stack.
1597 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1597 __ movq(rdx, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
1598 1598
1599 // Check that the receiver isn't a smi. 1599 // Check that the receiver isn't a smi.
1600 __ JumpIfSmi(rdx, &miss); 1600 __ JumpIfSmi(rdx, &miss);
1601 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1601 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
1602 name, &miss); 1602 name, &miss);
1603 } else { 1603 } else {
1604 ASSERT(cell->value() == *function); 1604 ASSERT(cell->value() == *function);
1605 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1605 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1606 &miss); 1606 &miss);
1607 GenerateLoadFunctionFromCell(cell, function, &miss); 1607 GenerateLoadFunctionFromCell(cell, function, &miss);
(...skipping 18 matching lines...) Expand all
1626 1626
1627 1627
1628 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1628 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1629 Handle<Object> object, 1629 Handle<Object> object,
1630 Handle<JSObject> holder, 1630 Handle<JSObject> holder,
1631 Handle<Cell> cell, 1631 Handle<Cell> cell,
1632 Handle<JSFunction> function, 1632 Handle<JSFunction> function,
1633 Handle<String> name, 1633 Handle<String> name,
1634 Code::StubType type) { 1634 Code::StubType type) {
1635 // ----------- S t a t e ------------- 1635 // ----------- S t a t e -------------
1636 // -- rcx : name 1636 // -- rcx : name
1637 // -- rsp[0] : return address 1637 // -- rsp[0] : return address
1638 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1638 // -- rsp[(argc - n - 1) * 8 + kPCOnStackSize] : arg[n] (zero-based)
1639 // -- ... 1639 // -- ...
1640 // -- rsp[(argc + 1) * 8] : receiver 1640 // -- rsp[argc * 8 + kPCOnStackSize] : receiver
1641 // ----------------------------------- 1641 // -----------------------------------
1642 1642
1643 // If object is not an array, bail out to regular call. 1643 // If object is not an array, bail out to regular call.
1644 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); 1644 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null();
1645 1645
1646 Label miss; 1646 Label miss;
1647 GenerateNameCheck(name, &miss); 1647 GenerateNameCheck(name, &miss);
1648 1648
1649 // Get the receiver from the stack. 1649 // Get the receiver from the stack.
1650 const int argc = arguments().immediate(); 1650 const int argc = arguments().immediate();
1651 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1651 __ movq(rdx, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
1652 1652
1653 // Check that the receiver isn't a smi. 1653 // Check that the receiver isn't a smi.
1654 __ JumpIfSmi(rdx, &miss); 1654 __ JumpIfSmi(rdx, &miss);
1655 1655
1656 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1656 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
1657 name, &miss); 1657 name, &miss);
1658 1658
1659 if (argc == 0) { 1659 if (argc == 0) {
1660 // Noop, return the length. 1660 // Noop, return the length.
1661 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); 1661 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset));
(...skipping 18 matching lines...) Expand all
1680 __ addl(rax, Immediate(argc)); 1680 __ addl(rax, Immediate(argc));
1681 1681
1682 // Get the elements' length into rcx. 1682 // Get the elements' length into rcx.
1683 __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); 1683 __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
1684 1684
1685 // Check if we could survive without allocation. 1685 // Check if we could survive without allocation.
1686 __ cmpl(rax, rcx); 1686 __ cmpl(rax, rcx);
1687 __ j(greater, &attempt_to_grow_elements); 1687 __ j(greater, &attempt_to_grow_elements);
1688 1688
1689 // Check if value is a smi. 1689 // Check if value is a smi.
1690 __ movq(rcx, Operand(rsp, argc * kPointerSize)); 1690 __ movq(rcx, Operand(rsp, kPCOnStackSize + (argc - 1) * kPointerSize));
1691 __ JumpIfNotSmi(rcx, &with_write_barrier); 1691 __ JumpIfNotSmi(rcx, &with_write_barrier);
1692 1692
1693 // Save new length. 1693 // Save new length.
1694 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1694 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1695 1695
1696 // Store the value. 1696 // Store the value.
1697 __ movq(FieldOperand(rdi, 1697 __ movq(FieldOperand(rdi,
1698 rax, 1698 rax,
1699 times_pointer_size, 1699 times_pointer_size,
1700 FixedArray::kHeaderSize - argc * kPointerSize), 1700 FixedArray::kHeaderSize - argc * kPointerSize),
(...skipping 14 matching lines...) Expand all
1715 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue); 1715 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue);
1716 __ addl(rax, Immediate(argc)); 1716 __ addl(rax, Immediate(argc));
1717 1717
1718 // Get the elements' length into rcx. 1718 // Get the elements' length into rcx.
1719 __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); 1719 __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
1720 1720
1721 // Check if we could survive without allocation. 1721 // Check if we could survive without allocation.
1722 __ cmpl(rax, rcx); 1722 __ cmpl(rax, rcx);
1723 __ j(greater, &call_builtin); 1723 __ j(greater, &call_builtin);
1724 1724
1725 __ movq(rcx, Operand(rsp, argc * kPointerSize)); 1725 __ movq(rcx, Operand(rsp, kPCOnStackSize + (argc - 1) * kPointerSize));
1726 __ StoreNumberToDoubleElements( 1726 __ StoreNumberToDoubleElements(
1727 rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize); 1727 rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize);
1728 1728
1729 // Save new length. 1729 // Save new length.
1730 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1730 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1731 __ Integer32ToSmi(rax, rax); // Return new length as smi. 1731 __ Integer32ToSmi(rax, rax); // Return new length as smi.
1732 __ ret((argc + 1) * kPointerSize); 1732 __ ret((argc + 1) * kPointerSize);
1733 1733
1734 __ bind(&with_write_barrier); 1734 __ bind(&with_write_barrier);
1735 1735
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1792 OMIT_SMI_CHECK); 1792 OMIT_SMI_CHECK);
1793 1793
1794 __ Integer32ToSmi(rax, rax); // Return new length as smi. 1794 __ Integer32ToSmi(rax, rax); // Return new length as smi.
1795 __ ret((argc + 1) * kPointerSize); 1795 __ ret((argc + 1) * kPointerSize);
1796 1796
1797 __ bind(&attempt_to_grow_elements); 1797 __ bind(&attempt_to_grow_elements);
1798 if (!FLAG_inline_new) { 1798 if (!FLAG_inline_new) {
1799 __ jmp(&call_builtin); 1799 __ jmp(&call_builtin);
1800 } 1800 }
1801 1801
1802 __ movq(rbx, Operand(rsp, argc * kPointerSize)); 1802 __ movq(rbx, Operand(rsp, kPCOnStackSize + (argc - 1) * kPointerSize));
1803 // Growing elements that are SMI-only requires special handling in case 1803 // Growing elements that are SMI-only requires special handling in case
1804 // the new element is non-Smi. For now, delegate to the builtin. 1804 // the new element is non-Smi. For now, delegate to the builtin.
1805 Label no_fast_elements_check; 1805 Label no_fast_elements_check;
1806 __ JumpIfSmi(rbx, &no_fast_elements_check); 1806 __ JumpIfSmi(rbx, &no_fast_elements_check);
1807 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); 1807 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
1808 __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar); 1808 __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar);
1809 __ bind(&no_fast_elements_check); 1809 __ bind(&no_fast_elements_check);
1810 1810
1811 ExternalReference new_space_allocation_top = 1811 ExternalReference new_space_allocation_top =
1812 ExternalReference::new_space_allocation_top_address(isolate()); 1812 ExternalReference::new_space_allocation_top_address(isolate());
(...skipping 28 matching lines...) Expand all
1841 } 1841 }
1842 1842
1843 // We know the elements array is in new space so we don't need the 1843 // We know the elements array is in new space so we don't need the
1844 // remembered set, but we just pushed a value onto it so we may have to 1844 // remembered set, but we just pushed a value onto it so we may have to
1845 // tell the incremental marker to rescan the object that we just grew. We 1845 // tell the incremental marker to rescan the object that we just grew. We
1846 // don't need to worry about the holes because they are in old space and 1846 // don't need to worry about the holes because they are in old space and
1847 // already marked black. 1847 // already marked black.
1848 __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET); 1848 __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
1849 1849
1850 // Restore receiver to rdx as finish sequence assumes it's here. 1850 // Restore receiver to rdx as finish sequence assumes it's here.
1851 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1851 __ movq(rdx, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
1852 1852
1853 // Increment element's and array's sizes. 1853 // Increment element's and array's sizes.
1854 __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset), 1854 __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset),
1855 Smi::FromInt(kAllocationDelta)); 1855 Smi::FromInt(kAllocationDelta));
1856 1856
1857 // Make new length a smi before returning it. 1857 // Make new length a smi before returning it.
1858 __ Integer32ToSmi(rax, rax); 1858 __ Integer32ToSmi(rax, rax);
1859 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1859 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1860 1860
1861 __ ret((argc + 1) * kPointerSize); 1861 __ ret((argc + 1) * kPointerSize);
(...skipping 15 matching lines...) Expand all
1877 1877
1878 1878
1879 Handle<Code> CallStubCompiler::CompileArrayPopCall( 1879 Handle<Code> CallStubCompiler::CompileArrayPopCall(
1880 Handle<Object> object, 1880 Handle<Object> object,
1881 Handle<JSObject> holder, 1881 Handle<JSObject> holder,
1882 Handle<Cell> cell, 1882 Handle<Cell> cell,
1883 Handle<JSFunction> function, 1883 Handle<JSFunction> function,
1884 Handle<String> name, 1884 Handle<String> name,
1885 Code::StubType type) { 1885 Code::StubType type) {
1886 // ----------- S t a t e ------------- 1886 // ----------- S t a t e -------------
1887 // -- rcx : name 1887 // -- rcx : name
1888 // -- rsp[0] : return address 1888 // -- rsp[0] : return address
1889 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1889 // -- rsp[(argc - n - 1) * 8 + kPCOnStackSize] : arg[n] (zero-based)
1890 // -- ... 1890 // -- ...
1891 // -- rsp[(argc + 1) * 8] : receiver 1891 // -- rsp[argc * 8 + kPCOnStackSize] : receiver
1892 // ----------------------------------- 1892 // -----------------------------------
1893 1893
1894 // If object is not an array, bail out to regular call. 1894 // If object is not an array, bail out to regular call.
1895 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); 1895 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null();
1896 1896
1897 Label miss, return_undefined, call_builtin; 1897 Label miss, return_undefined, call_builtin;
1898 GenerateNameCheck(name, &miss); 1898 GenerateNameCheck(name, &miss);
1899 1899
1900 // Get the receiver from the stack. 1900 // Get the receiver from the stack.
1901 const int argc = arguments().immediate(); 1901 const int argc = arguments().immediate();
1902 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1902 __ movq(rdx, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
1903 1903
1904 // Check that the receiver isn't a smi. 1904 // Check that the receiver isn't a smi.
1905 __ JumpIfSmi(rdx, &miss); 1905 __ JumpIfSmi(rdx, &miss);
1906 1906
1907 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1907 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
1908 name, &miss); 1908 name, &miss);
1909 1909
1910 // Get the elements array of the object. 1910 // Get the elements array of the object.
1911 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); 1911 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset));
1912 1912
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 1959
1960 1960
1961 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( 1961 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
1962 Handle<Object> object, 1962 Handle<Object> object,
1963 Handle<JSObject> holder, 1963 Handle<JSObject> holder,
1964 Handle<Cell> cell, 1964 Handle<Cell> cell,
1965 Handle<JSFunction> function, 1965 Handle<JSFunction> function,
1966 Handle<String> name, 1966 Handle<String> name,
1967 Code::StubType type) { 1967 Code::StubType type) {
1968 // ----------- S t a t e ------------- 1968 // ----------- S t a t e -------------
1969 // -- rcx : function name 1969 // -- rcx : function name
1970 // -- rsp[0] : return address 1970 // -- rsp[0] : return address
1971 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1971 // -- rsp[(argc - n - 1) * 8 + kPCOnStackSize] : arg[n] (zero-based)
1972 // -- ... 1972 // -- ...
1973 // -- rsp[(argc + 1) * 8] : receiver 1973 // -- rsp[argc * 8 + kPCOnStackSize] : receiver
1974 // ----------------------------------- 1974 // -----------------------------------
1975 1975
1976 // If object is not a string, bail out to regular call. 1976 // If object is not a string, bail out to regular call.
1977 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1977 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
1978 1978
1979 const int argc = arguments().immediate(); 1979 const int argc = arguments().immediate();
1980 1980
1981 Label miss; 1981 Label miss;
1982 Label name_miss; 1982 Label name_miss;
1983 Label index_out_of_range; 1983 Label index_out_of_range;
(...skipping 11 matching lines...) Expand all
1995 rax, 1995 rax,
1996 &miss); 1996 &miss);
1997 ASSERT(!object.is_identical_to(holder)); 1997 ASSERT(!object.is_identical_to(holder));
1998 CheckPrototypes( 1998 CheckPrototypes(
1999 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 1999 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2000 rax, holder, rbx, rdx, rdi, name, &miss); 2000 rax, holder, rbx, rdx, rdi, name, &miss);
2001 2001
2002 Register receiver = rbx; 2002 Register receiver = rbx;
2003 Register index = rdi; 2003 Register index = rdi;
2004 Register result = rax; 2004 Register result = rax;
2005 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); 2005 __ movq(receiver, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
2006 if (argc > 0) { 2006 if (argc > 0) {
2007 __ movq(index, Operand(rsp, (argc - 0) * kPointerSize)); 2007 __ movq(index, Operand(rsp, kPCOnStackSize + (argc - 1) * kPointerSize));
2008 } else { 2008 } else {
2009 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2009 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2010 } 2010 }
2011 2011
2012 StringCharCodeAtGenerator generator(receiver, 2012 StringCharCodeAtGenerator generator(receiver,
2013 index, 2013 index,
2014 result, 2014 result,
2015 &miss, // When not a string. 2015 &miss, // When not a string.
2016 &miss, // When not a number. 2016 &miss, // When not a number.
2017 index_out_of_range_label, 2017 index_out_of_range_label,
(...skipping 22 matching lines...) Expand all
2040 2040
2041 2041
2042 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2042 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2043 Handle<Object> object, 2043 Handle<Object> object,
2044 Handle<JSObject> holder, 2044 Handle<JSObject> holder,
2045 Handle<Cell> cell, 2045 Handle<Cell> cell,
2046 Handle<JSFunction> function, 2046 Handle<JSFunction> function,
2047 Handle<String> name, 2047 Handle<String> name,
2048 Code::StubType type) { 2048 Code::StubType type) {
2049 // ----------- S t a t e ------------- 2049 // ----------- S t a t e -------------
2050 // -- rcx : function name 2050 // -- rcx : function name
2051 // -- rsp[0] : return address 2051 // -- rsp[0] : return address
2052 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 2052 // -- rsp[(argc - n - 1) * 8 + kPCOnStackSize] : arg[n] (zero-based)
2053 // -- ... 2053 // -- ...
2054 // -- rsp[(argc + 1) * 8] : receiver 2054 // -- rsp[argc * 8 + kPCOnStackSize] : receiver
2055 // ----------------------------------- 2055 // -----------------------------------
2056 2056
2057 // If object is not a string, bail out to regular call. 2057 // If object is not a string, bail out to regular call.
2058 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 2058 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2059 2059
2060 const int argc = arguments().immediate(); 2060 const int argc = arguments().immediate();
2061 Label miss; 2061 Label miss;
2062 Label name_miss; 2062 Label name_miss;
2063 Label index_out_of_range; 2063 Label index_out_of_range;
2064 Label* index_out_of_range_label = &index_out_of_range; 2064 Label* index_out_of_range_label = &index_out_of_range;
(...skipping 11 matching lines...) Expand all
2076 &miss); 2076 &miss);
2077 ASSERT(!object.is_identical_to(holder)); 2077 ASSERT(!object.is_identical_to(holder));
2078 CheckPrototypes( 2078 CheckPrototypes(
2079 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2079 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2080 rax, holder, rbx, rdx, rdi, name, &miss); 2080 rax, holder, rbx, rdx, rdi, name, &miss);
2081 2081
2082 Register receiver = rax; 2082 Register receiver = rax;
2083 Register index = rdi; 2083 Register index = rdi;
2084 Register scratch = rdx; 2084 Register scratch = rdx;
2085 Register result = rax; 2085 Register result = rax;
2086 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); 2086 __ movq(receiver, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
2087 if (argc > 0) { 2087 if (argc > 0) {
2088 __ movq(index, Operand(rsp, (argc - 0) * kPointerSize)); 2088 __ movq(index, Operand(rsp, kPCOnStackSize + (argc - 1) * kPointerSize));
2089 } else { 2089 } else {
2090 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2090 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2091 } 2091 }
2092 2092
2093 StringCharAtGenerator generator(receiver, 2093 StringCharAtGenerator generator(receiver,
2094 index, 2094 index,
2095 scratch, 2095 scratch,
2096 result, 2096 result,
2097 &miss, // When not a string. 2097 &miss, // When not a string.
2098 &miss, // When not a number. 2098 &miss, // When not a number.
(...skipping 22 matching lines...) Expand all
2121 2121
2122 2122
2123 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2123 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2124 Handle<Object> object, 2124 Handle<Object> object,
2125 Handle<JSObject> holder, 2125 Handle<JSObject> holder,
2126 Handle<Cell> cell, 2126 Handle<Cell> cell,
2127 Handle<JSFunction> function, 2127 Handle<JSFunction> function,
2128 Handle<String> name, 2128 Handle<String> name,
2129 Code::StubType type) { 2129 Code::StubType type) {
2130 // ----------- S t a t e ------------- 2130 // ----------- S t a t e -------------
2131 // -- rcx : function name 2131 // -- rcx : function name
2132 // -- rsp[0] : return address 2132 // -- rsp[0] : return address
2133 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 2133 // -- rsp[(argc - n - 1) * 8 + kPCOnStackSize] : arg[n] (zero-based)
2134 // -- ... 2134 // -- ...
2135 // -- rsp[(argc + 1) * 8] : receiver 2135 // -- rsp[argc * 8 + kPCOnStackSize] : receiver
2136 // ----------------------------------- 2136 // -----------------------------------
2137 2137
2138 // If the object is not a JSObject or we got an unexpected number of 2138 // If the object is not a JSObject or we got an unexpected number of
2139 // arguments, bail out to the regular call. 2139 // arguments, bail out to the regular call.
2140 const int argc = arguments().immediate(); 2140 const int argc = arguments().immediate();
2141 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2141 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2142 2142
2143 Label miss; 2143 Label miss;
2144 GenerateNameCheck(name, &miss); 2144 GenerateNameCheck(name, &miss);
2145 2145
2146 if (cell.is_null()) { 2146 if (cell.is_null()) {
2147 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2147 __ movq(rdx, Operand(rsp, kPCOnStackSize + 1 * kPointerSize));
2148 __ JumpIfSmi(rdx, &miss); 2148 __ JumpIfSmi(rdx, &miss);
2149 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2149 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
2150 name, &miss); 2150 name, &miss);
2151 } else { 2151 } else {
2152 ASSERT(cell->value() == *function); 2152 ASSERT(cell->value() == *function);
2153 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2153 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2154 &miss); 2154 &miss);
2155 GenerateLoadFunctionFromCell(cell, function, &miss); 2155 GenerateLoadFunctionFromCell(cell, function, &miss);
2156 } 2156 }
2157 2157
2158 // Load the char code argument. 2158 // Load the char code argument.
2159 Register code = rbx; 2159 Register code = rbx;
2160 __ movq(code, Operand(rsp, 1 * kPointerSize)); 2160 __ movq(code, Operand(rsp, kPCOnStackSize));
2161 2161
2162 // Check the code is a smi. 2162 // Check the code is a smi.
2163 Label slow; 2163 Label slow;
2164 __ JumpIfNotSmi(code, &slow); 2164 __ JumpIfNotSmi(code, &slow);
2165 2165
2166 // Convert the smi code to uint16. 2166 // Convert the smi code to uint16.
2167 __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); 2167 __ SmiAndConstant(code, code, Smi::FromInt(0xffff));
2168 2168
2169 StringCharFromCodeGenerator generator(code, rax); 2169 StringCharFromCodeGenerator generator(code, rax);
2170 generator.GenerateFast(masm()); 2170 generator.GenerateFast(masm());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2205 2205
2206 2206
2207 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2207 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2208 Handle<Object> object, 2208 Handle<Object> object,
2209 Handle<JSObject> holder, 2209 Handle<JSObject> holder,
2210 Handle<Cell> cell, 2210 Handle<Cell> cell,
2211 Handle<JSFunction> function, 2211 Handle<JSFunction> function,
2212 Handle<String> name, 2212 Handle<String> name,
2213 Code::StubType type) { 2213 Code::StubType type) {
2214 // ----------- S t a t e ------------- 2214 // ----------- S t a t e -------------
2215 // -- rcx : function name 2215 // -- rcx : function name
2216 // -- rsp[0] : return address 2216 // -- rsp[0] : return address
2217 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 2217 // -- rsp[(argc - n - 1) * 8 + kPCOnStackSize] : arg[n] (zero-based)
2218 // -- ... 2218 // -- ...
2219 // -- rsp[(argc + 1) * 8] : receiver 2219 // -- rsp[argc * 8 + kPCOnStackSize] : receiver
2220 // ----------------------------------- 2220 // -----------------------------------
2221 2221
2222 // If the object is not a JSObject or we got an unexpected number of 2222 // If the object is not a JSObject or we got an unexpected number of
2223 // arguments, bail out to the regular call. 2223 // arguments, bail out to the regular call.
2224 const int argc = arguments().immediate(); 2224 const int argc = arguments().immediate();
2225 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2225 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2226 2226
2227 Label miss; 2227 Label miss;
2228 GenerateNameCheck(name, &miss); 2228 GenerateNameCheck(name, &miss);
2229 2229
2230 if (cell.is_null()) { 2230 if (cell.is_null()) {
2231 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2231 __ movq(rdx, Operand(rsp, kPCOnStackSize + 1 * kPointerSize));
2232 __ JumpIfSmi(rdx, &miss); 2232 __ JumpIfSmi(rdx, &miss);
2233 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2233 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
2234 name, &miss); 2234 name, &miss);
2235 } else { 2235 } else {
2236 ASSERT(cell->value() == *function); 2236 ASSERT(cell->value() == *function);
2237 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2237 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2238 &miss); 2238 &miss);
2239 GenerateLoadFunctionFromCell(cell, function, &miss); 2239 GenerateLoadFunctionFromCell(cell, function, &miss);
2240 } 2240 }
2241 // Load the (only) argument into rax. 2241 // Load the (only) argument into rax.
2242 __ movq(rax, Operand(rsp, 1 * kPointerSize)); 2242 __ movq(rax, Operand(rsp, kPCOnStackSize));
2243 2243
2244 // Check if the argument is a smi. 2244 // Check if the argument is a smi.
2245 Label not_smi; 2245 Label not_smi;
2246 STATIC_ASSERT(kSmiTag == 0); 2246 STATIC_ASSERT(kSmiTag == 0);
2247 __ JumpIfNotSmi(rax, &not_smi); 2247 __ JumpIfNotSmi(rax, &not_smi);
2248 __ SmiToInteger32(rax, rax); 2248 __ SmiToInteger32(rax, rax);
2249 2249
2250 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0 2250 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
2251 // otherwise. 2251 // otherwise.
2252 __ movl(rbx, rax); 2252 __ movl(rbx, rax);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 if (!object->IsJSObject()) return Handle<Code>::null(); 2325 if (!object->IsJSObject()) return Handle<Code>::null();
2326 int depth = optimization.GetPrototypeDepthOfExpectedType( 2326 int depth = optimization.GetPrototypeDepthOfExpectedType(
2327 Handle<JSObject>::cast(object), holder); 2327 Handle<JSObject>::cast(object), holder);
2328 if (depth == kInvalidProtoDepth) return Handle<Code>::null(); 2328 if (depth == kInvalidProtoDepth) return Handle<Code>::null();
2329 2329
2330 Label miss, miss_before_stack_reserved; 2330 Label miss, miss_before_stack_reserved;
2331 GenerateNameCheck(name, &miss_before_stack_reserved); 2331 GenerateNameCheck(name, &miss_before_stack_reserved);
2332 2332
2333 // Get the receiver from the stack. 2333 // Get the receiver from the stack.
2334 const int argc = arguments().immediate(); 2334 const int argc = arguments().immediate();
2335 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2335 __ movq(rdx, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
2336 2336
2337 // Check that the receiver isn't a smi. 2337 // Check that the receiver isn't a smi.
2338 __ JumpIfSmi(rdx, &miss_before_stack_reserved); 2338 __ JumpIfSmi(rdx, &miss_before_stack_reserved);
2339 2339
2340 Counters* counters = isolate()->counters(); 2340 Counters* counters = isolate()->counters();
2341 __ IncrementCounter(counters->call_const(), 1); 2341 __ IncrementCounter(counters->call_const(), 1);
2342 __ IncrementCounter(counters->call_const_fast_api(), 1); 2342 __ IncrementCounter(counters->call_const_fast_api(), 1);
2343 2343
2344 // Allocate space for v8::Arguments implicit values. Must be initialized 2344 // Allocate space for v8::Arguments implicit values. Must be initialized
2345 // before calling any runtime function. 2345 // before calling any runtime function.
(...skipping 19 matching lines...) Expand all
2365 return GetCode(function); 2365 return GetCode(function);
2366 } 2366 }
2367 2367
2368 2368
2369 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2369 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
2370 Handle<JSObject> holder, 2370 Handle<JSObject> holder,
2371 Handle<Name> name, 2371 Handle<Name> name,
2372 CheckType check, 2372 CheckType check,
2373 Label* success) { 2373 Label* success) {
2374 // ----------- S t a t e ------------- 2374 // ----------- S t a t e -------------
2375 // rcx : function name 2375 // rcx : function name
2376 // rsp[0] : return address 2376 // rsp[0] : return address
2377 // rsp[8] : argument argc 2377 // rsp[8] : argument argc
2378 // rsp[16] : argument argc - 1 2378 // rsp[16] : argument argc - 1
2379 // ... 2379 // ...
2380 // rsp[argc * 8] : argument 1 2380 // rsp[argc * 8] : argument 1
2381 // rsp[(argc + 1) * 8] : argument 0 = receiver 2381 // rsp[argc * 8 + kPCOnStackSize] : argument 0 = receiver
2382 // ----------------------------------- 2382 // -----------------------------------
2383 Label miss; 2383 Label miss;
2384 GenerateNameCheck(name, &miss); 2384 GenerateNameCheck(name, &miss);
2385 2385
2386 // Get the receiver from the stack. 2386 // Get the receiver from the stack.
2387 const int argc = arguments().immediate(); 2387 const int argc = arguments().immediate();
2388 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2388 __ movq(rdx, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
2389 2389
2390 // Check that the receiver isn't a smi. 2390 // Check that the receiver isn't a smi.
2391 if (check != NUMBER_CHECK) { 2391 if (check != NUMBER_CHECK) {
2392 __ JumpIfSmi(rdx, &miss); 2392 __ JumpIfSmi(rdx, &miss);
2393 } 2393 }
2394 2394
2395 // Make sure that it's okay not to patch the on stack receiver 2395 // Make sure that it's okay not to patch the on stack receiver
2396 // unless we're doing a receiver map check. 2396 // unless we're doing a receiver map check.
2397 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2397 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2398 2398
2399 Counters* counters = isolate()->counters(); 2399 Counters* counters = isolate()->counters();
2400 switch (check) { 2400 switch (check) {
2401 case RECEIVER_MAP_CHECK: 2401 case RECEIVER_MAP_CHECK:
2402 __ IncrementCounter(counters->call_const(), 1); 2402 __ IncrementCounter(counters->call_const(), 1);
2403 2403
2404 // Check that the maps haven't changed. 2404 // Check that the maps haven't changed.
2405 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, 2405 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax,
2406 rdi, name, &miss); 2406 rdi, name, &miss);
2407 2407
2408 // Patch the receiver on the stack with the global proxy if 2408 // Patch the receiver on the stack with the global proxy if
2409 // necessary. 2409 // necessary.
2410 if (object->IsGlobalObject()) { 2410 if (object->IsGlobalObject()) {
2411 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2411 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2412 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2412 __ movq(Operand(rsp, kPCOnStackSize + argc * kPointerSize), rdx);
2413 } 2413 }
2414 break; 2414 break;
2415 2415
2416 case STRING_CHECK: 2416 case STRING_CHECK:
2417 // Check that the object is a string. 2417 // Check that the object is a string.
2418 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); 2418 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
2419 __ j(above_equal, &miss); 2419 __ j(above_equal, &miss);
2420 // Check that the maps starting from the prototype haven't changed. 2420 // Check that the maps starting from the prototype haven't changed.
2421 GenerateDirectLoadGlobalFunctionPrototype( 2421 GenerateDirectLoadGlobalFunctionPrototype(
2422 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss); 2422 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2511 2511
2512 // Return the generated code. 2512 // Return the generated code.
2513 return GetCode(function); 2513 return GetCode(function);
2514 } 2514 }
2515 2515
2516 2516
2517 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2517 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2518 Handle<JSObject> holder, 2518 Handle<JSObject> holder,
2519 Handle<Name> name) { 2519 Handle<Name> name) {
2520 // ----------- S t a t e ------------- 2520 // ----------- S t a t e -------------
2521 // rcx : function name 2521 // rcx : function name
2522 // rsp[0] : return address 2522 // rsp[0] : return address
2523 // rsp[8] : argument argc 2523 // rsp[8] : argument argc
2524 // rsp[16] : argument argc - 1 2524 // rsp[16] : argument argc - 1
2525 // ... 2525 // ...
2526 // rsp[argc * 8] : argument 1 2526 // rsp[argc * 8] : argument 1
2527 // rsp[(argc + 1) * 8] : argument 0 = receiver 2527 // rsp[argc * 8 + kPCOnStackSize] : argument 0 = receiver
2528 // ----------------------------------- 2528 // -----------------------------------
2529 Label miss; 2529 Label miss;
2530 GenerateNameCheck(name, &miss); 2530 GenerateNameCheck(name, &miss);
2531 2531
2532 // Get the number of arguments. 2532 // Get the number of arguments.
2533 const int argc = arguments().immediate(); 2533 const int argc = arguments().immediate();
2534 2534
2535 LookupResult lookup(isolate()); 2535 LookupResult lookup(isolate());
2536 LookupPostInterceptor(holder, name, &lookup); 2536 LookupPostInterceptor(holder, name, &lookup);
2537 2537
2538 // Get the receiver from the stack. 2538 // Get the receiver from the stack.
2539 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2539 __ movq(rdx, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
2540 2540
2541 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); 2541 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_);
2542 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, 2542 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
2543 &miss); 2543 &miss);
2544 2544
2545 // Restore receiver. 2545 // Restore receiver.
2546 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2546 __ movq(rdx, Operand(rsp, kPCOnStackSize + argc * kPointerSize));
2547 2547
2548 // Check that the function really is a function. 2548 // Check that the function really is a function.
2549 __ JumpIfSmi(rax, &miss); 2549 __ JumpIfSmi(rax, &miss);
2550 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 2550 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
2551 __ j(not_equal, &miss); 2551 __ j(not_equal, &miss);
2552 2552
2553 // Patch the receiver on the stack with the global proxy if 2553 // Patch the receiver on the stack with the global proxy if
2554 // necessary. 2554 // necessary.
2555 if (object->IsGlobalObject()) { 2555 if (object->IsGlobalObject()) {
2556 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2556 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2557 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2557 __ movq(Operand(rsp, kPCOnStackSize + argc * kPointerSize), rdx);
2558 } 2558 }
2559 2559
2560 // Invoke the function. 2560 // Invoke the function.
2561 __ movq(rdi, rax); 2561 __ movq(rdi, rax);
2562 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2562 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2563 ? CALL_AS_FUNCTION 2563 ? CALL_AS_FUNCTION
2564 : CALL_AS_METHOD; 2564 : CALL_AS_METHOD;
2565 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 2565 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2566 NullCallWrapper(), call_kind); 2566 NullCallWrapper(), call_kind);
2567 2567
2568 // Handle load cache miss. 2568 // Handle load cache miss.
2569 __ bind(&miss); 2569 __ bind(&miss);
2570 GenerateMissBranch(); 2570 GenerateMissBranch();
2571 2571
2572 // Return the generated code. 2572 // Return the generated code.
2573 return GetCode(Code::INTERCEPTOR, name); 2573 return GetCode(Code::INTERCEPTOR, name);
2574 } 2574 }
2575 2575
2576 2576
2577 Handle<Code> CallStubCompiler::CompileCallGlobal( 2577 Handle<Code> CallStubCompiler::CompileCallGlobal(
2578 Handle<JSObject> object, 2578 Handle<JSObject> object,
2579 Handle<GlobalObject> holder, 2579 Handle<GlobalObject> holder,
2580 Handle<PropertyCell> cell, 2580 Handle<PropertyCell> cell,
2581 Handle<JSFunction> function, 2581 Handle<JSFunction> function,
2582 Handle<Name> name) { 2582 Handle<Name> name) {
2583 // ----------- S t a t e ------------- 2583 // ----------- S t a t e -------------
2584 // rcx : function name 2584 // rcx : function name
2585 // rsp[0] : return address 2585 // rsp[0] : return address
2586 // rsp[8] : argument argc 2586 // rsp[8] : argument argc
2587 // rsp[16] : argument argc - 1 2587 // rsp[16] : argument argc - 1
2588 // ... 2588 // ...
2589 // rsp[argc * 8] : argument 1 2589 // rsp[argc * 8] : argument 1
2590 // rsp[(argc + 1) * 8] : argument 0 = receiver 2590 // rsp[argc * 8 + kPCOnStackSize] : argument 0 = receiver
2591 // ----------------------------------- 2591 // -----------------------------------
2592 2592
2593 if (HasCustomCallGenerator(function)) { 2593 if (HasCustomCallGenerator(function)) {
2594 Handle<Code> code = CompileCustomCall( 2594 Handle<Code> code = CompileCustomCall(
2595 object, holder, cell, function, Handle<String>::cast(name), 2595 object, holder, cell, function, Handle<String>::cast(name),
2596 Code::NORMAL); 2596 Code::NORMAL);
2597 // A null handle means bail out to the regular compiler code below. 2597 // A null handle means bail out to the regular compiler code below.
2598 if (!code.is_null()) return code; 2598 if (!code.is_null()) return code;
2599 } 2599 }
2600 2600
2601 Label miss; 2601 Label miss;
2602 GenerateNameCheck(name, &miss); 2602 GenerateNameCheck(name, &miss);
2603 2603
2604 // Get the number of arguments. 2604 // Get the number of arguments.
2605 const int argc = arguments().immediate(); 2605 const int argc = arguments().immediate();
2606 GenerateGlobalReceiverCheck(object, holder, name, &miss); 2606 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2607 GenerateLoadFunctionFromCell(cell, function, &miss); 2607 GenerateLoadFunctionFromCell(cell, function, &miss);
2608 2608
2609 // Patch the receiver on the stack with the global proxy. 2609 // Patch the receiver on the stack with the global proxy.
2610 if (object->IsGlobalObject()) { 2610 if (object->IsGlobalObject()) {
2611 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2611 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2612 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2612 __ movq(Operand(rsp, kPCOnStackSize + argc * kPointerSize), rdx);
2613 } 2613 }
2614 2614
2615 // Set up the context (function already in rdi). 2615 // Set up the context (function already in rdi).
2616 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 2616 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2617 2617
2618 // Jump to the cached code (tail call). 2618 // Jump to the cached code (tail call).
2619 Counters* counters = isolate()->counters(); 2619 Counters* counters = isolate()->counters();
2620 __ IncrementCounter(counters->call_global_inline(), 1); 2620 __ IncrementCounter(counters->call_global_inline(), 1);
2621 ParameterCount expected(function->shared()->formal_parameter_count()); 2621 ParameterCount expected(function->shared()->formal_parameter_count());
2622 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2622 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
3512 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3512 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3513 } 3513 }
3514 } 3514 }
3515 3515
3516 3516
3517 #undef __ 3517 #undef __
3518 3518
3519 } } // namespace v8::internal 3519 } } // namespace v8::internal
3520 3520
3521 #endif // V8_TARGET_ARCH_X64 3521 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/x64/builtins-x64.cc ('K') | « src/x64/ic-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698