| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 Label* if_false, | 542 Label* if_false, |
| 543 Label* fall_through) { | 543 Label* fall_through) { |
| 544 // Emit the inlined tests assumed by the stub. | 544 // Emit the inlined tests assumed by the stub. |
| 545 __ CompareRoot(result_register(), Heap::kUndefinedValueRootIndex); | 545 __ CompareRoot(result_register(), Heap::kUndefinedValueRootIndex); |
| 546 __ j(equal, if_false); | 546 __ j(equal, if_false); |
| 547 __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); | 547 __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); |
| 548 __ j(equal, if_true); | 548 __ j(equal, if_true); |
| 549 __ CompareRoot(result_register(), Heap::kFalseValueRootIndex); | 549 __ CompareRoot(result_register(), Heap::kFalseValueRootIndex); |
| 550 __ j(equal, if_false); | 550 __ j(equal, if_false); |
| 551 STATIC_ASSERT(kSmiTag == 0); | 551 STATIC_ASSERT(kSmiTag == 0); |
| 552 __ SmiCompare(result_register(), Smi::FromInt(0)); | 552 __ Cmp(result_register(), Smi::FromInt(0)); |
| 553 __ j(equal, if_false); | 553 __ j(equal, if_false); |
| 554 Condition is_smi = masm_->CheckSmi(result_register()); | 554 Condition is_smi = masm_->CheckSmi(result_register()); |
| 555 __ j(is_smi, if_true); | 555 __ j(is_smi, if_true); |
| 556 | 556 |
| 557 // Call the ToBoolean stub for all other cases. | 557 // Call the ToBoolean stub for all other cases. |
| 558 ToBooleanStub stub; | 558 ToBooleanStub stub; |
| 559 __ push(result_register()); | 559 __ push(result_register()); |
| 560 __ CallStub(&stub); | 560 __ CallStub(&stub); |
| 561 __ testq(rax, rax); | 561 __ testq(rax, rax); |
| 562 | 562 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 VisitForAccumulatorValue(function); | 731 VisitForAccumulatorValue(function); |
| 732 __ pop(rdx); | 732 __ pop(rdx); |
| 733 } else { | 733 } else { |
| 734 __ movq(rdx, rax); | 734 __ movq(rdx, rax); |
| 735 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); | 735 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); |
| 736 } | 736 } |
| 737 ASSERT(prop->key()->AsLiteral() != NULL && | 737 ASSERT(prop->key()->AsLiteral() != NULL && |
| 738 prop->key()->AsLiteral()->handle()->IsSmi()); | 738 prop->key()->AsLiteral()->handle()->IsSmi()); |
| 739 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 739 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 740 | 740 |
| 741 Handle<Code> ic(isolate()->builtins()->builtin(is_strict() | 741 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() |
| 742 ? Builtins::KeyedStoreIC_Initialize_Strict | 742 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 743 : Builtins::KeyedStoreIC_Initialize)); | 743 : Builtins::KeyedStoreIC_Initialize)); |
| 744 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 744 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 745 } | 745 } |
| 746 } | 746 } |
| 747 } | 747 } |
| 748 | 748 |
| 749 | 749 |
| 750 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 750 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 751 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 751 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 __ movq(rcx, Operand(rsp, 4 * kPointerSize)); | 988 __ movq(rcx, Operand(rsp, 4 * kPointerSize)); |
| 989 __ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); | 989 __ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); |
| 990 __ j(equal, &update_each); | 990 __ j(equal, &update_each); |
| 991 | 991 |
| 992 // Convert the entry to a string or null if it isn't a property | 992 // Convert the entry to a string or null if it isn't a property |
| 993 // anymore. If the property has been removed while iterating, we | 993 // anymore. If the property has been removed while iterating, we |
| 994 // just skip it. | 994 // just skip it. |
| 995 __ push(rcx); // Enumerable. | 995 __ push(rcx); // Enumerable. |
| 996 __ push(rbx); // Current entry. | 996 __ push(rbx); // Current entry. |
| 997 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); | 997 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); |
| 998 __ SmiCompare(rax, Smi::FromInt(0)); | 998 __ Cmp(rax, Smi::FromInt(0)); |
| 999 __ j(equal, loop_statement.continue_target()); | 999 __ j(equal, loop_statement.continue_target()); |
| 1000 __ movq(rbx, rax); | 1000 __ movq(rbx, rax); |
| 1001 | 1001 |
| 1002 // Update the 'each' property or variable from the possibly filtered | 1002 // Update the 'each' property or variable from the possibly filtered |
| 1003 // entry in register rbx. | 1003 // entry in register rbx. |
| 1004 __ bind(&update_each); | 1004 __ bind(&update_each); |
| 1005 __ movq(result_register(), rbx); | 1005 __ movq(result_register(), rbx); |
| 1006 // Perform the assignment as if via '='. | 1006 // Perform the assignment as if via '='. |
| 1007 { EffectContext context(this); | 1007 { EffectContext context(this); |
| 1008 EmitAssignment(stmt->each(), stmt->AssignmentId()); | 1008 EmitAssignment(stmt->each(), stmt->AssignmentId()); |
| (...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1745 EmitVariableAssignment(var, Token::ASSIGN); | 1745 EmitVariableAssignment(var, Token::ASSIGN); |
| 1746 break; | 1746 break; |
| 1747 } | 1747 } |
| 1748 case NAMED_PROPERTY: { | 1748 case NAMED_PROPERTY: { |
| 1749 __ push(rax); // Preserve value. | 1749 __ push(rax); // Preserve value. |
| 1750 VisitForAccumulatorValue(prop->obj()); | 1750 VisitForAccumulatorValue(prop->obj()); |
| 1751 __ movq(rdx, rax); | 1751 __ movq(rdx, rax); |
| 1752 __ pop(rax); // Restore value. | 1752 __ pop(rax); // Restore value. |
| 1753 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1753 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 1754 Handle<Code> ic(isolate()->builtins()->builtin( | 1754 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1755 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1755 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1756 : Builtins::StoreIC_Initialize)); | 1756 : Builtins::StoreIC_Initialize)); |
| 1757 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1757 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1758 break; | 1758 break; |
| 1759 } | 1759 } |
| 1760 case KEYED_PROPERTY: { | 1760 case KEYED_PROPERTY: { |
| 1761 __ push(rax); // Preserve value. | 1761 __ push(rax); // Preserve value. |
| 1762 if (prop->is_synthetic()) { | 1762 if (prop->is_synthetic()) { |
| 1763 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1763 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
| 1764 ASSERT(prop->key()->AsLiteral() != NULL); | 1764 ASSERT(prop->key()->AsLiteral() != NULL); |
| 1765 { AccumulatorValueContext for_object(this); | 1765 { AccumulatorValueContext for_object(this); |
| 1766 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1766 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
| 1767 } | 1767 } |
| 1768 __ movq(rdx, rax); | 1768 __ movq(rdx, rax); |
| 1769 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1769 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 1770 } else { | 1770 } else { |
| 1771 VisitForStackValue(prop->obj()); | 1771 VisitForStackValue(prop->obj()); |
| 1772 VisitForAccumulatorValue(prop->key()); | 1772 VisitForAccumulatorValue(prop->key()); |
| 1773 __ movq(rcx, rax); | 1773 __ movq(rcx, rax); |
| 1774 __ pop(rdx); | 1774 __ pop(rdx); |
| 1775 } | 1775 } |
| 1776 __ pop(rax); // Restore value. | 1776 __ pop(rax); // Restore value. |
| 1777 Handle<Code> ic(isolate()->builtins()->builtin( | 1777 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1778 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 1778 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1779 : Builtins::KeyedStoreIC_Initialize)); | 1779 : Builtins::KeyedStoreIC_Initialize)); |
| 1780 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1780 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1781 break; | 1781 break; |
| 1782 } | 1782 } |
| 1783 } | 1783 } |
| 1784 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1784 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1785 context()->Plug(rax); | 1785 context()->Plug(rax); |
| 1786 } | 1786 } |
| 1787 | 1787 |
| 1788 | 1788 |
| 1789 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1789 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1790 Token::Value op) { | 1790 Token::Value op) { |
| 1791 // Left-hand sides that rewrite to explicit property accesses do not reach | 1791 // Left-hand sides that rewrite to explicit property accesses do not reach |
| 1792 // here. | 1792 // here. |
| 1793 ASSERT(var != NULL); | 1793 ASSERT(var != NULL); |
| 1794 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1794 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1795 | 1795 |
| 1796 if (var->is_global()) { | 1796 if (var->is_global()) { |
| 1797 ASSERT(!var->is_this()); | 1797 ASSERT(!var->is_this()); |
| 1798 // Assignment to a global variable. Use inline caching for the | 1798 // Assignment to a global variable. Use inline caching for the |
| 1799 // assignment. Right-hand-side value is passed in rax, variable name in | 1799 // assignment. Right-hand-side value is passed in rax, variable name in |
| 1800 // rcx, and the global object on the stack. | 1800 // rcx, and the global object on the stack. |
| 1801 __ Move(rcx, var->name()); | 1801 __ Move(rcx, var->name()); |
| 1802 __ movq(rdx, GlobalObjectOperand()); | 1802 __ movq(rdx, GlobalObjectOperand()); |
| 1803 Handle<Code> ic(isolate()->builtins()->builtin(is_strict() | 1803 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() |
| 1804 ? Builtins::StoreIC_Initialize_Strict | 1804 ? Builtins::StoreIC_Initialize_Strict |
| 1805 : Builtins::StoreIC_Initialize)); | 1805 : Builtins::StoreIC_Initialize)); |
| 1806 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1806 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1807 | 1807 |
| 1808 } else if (op == Token::INIT_CONST) { | 1808 } else if (op == Token::INIT_CONST) { |
| 1809 // Like var declarations, const declarations are hoisted to function | 1809 // Like var declarations, const declarations are hoisted to function |
| 1810 // scope. However, unlike var initializers, const initializers are able | 1810 // scope. However, unlike var initializers, const initializers are able |
| 1811 // to drill a hole to that function context, even from inside a 'with' | 1811 // to drill a hole to that function context, even from inside a 'with' |
| 1812 // context. We thus bypass the normal static scope lookup. | 1812 // context. We thus bypass the normal static scope lookup. |
| 1813 Slot* slot = var->AsSlot(); | 1813 Slot* slot = var->AsSlot(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1897 | 1897 |
| 1898 // Record source code position before IC call. | 1898 // Record source code position before IC call. |
| 1899 SetSourcePosition(expr->position()); | 1899 SetSourcePosition(expr->position()); |
| 1900 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1900 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 1901 if (expr->ends_initialization_block()) { | 1901 if (expr->ends_initialization_block()) { |
| 1902 __ movq(rdx, Operand(rsp, 0)); | 1902 __ movq(rdx, Operand(rsp, 0)); |
| 1903 } else { | 1903 } else { |
| 1904 __ pop(rdx); | 1904 __ pop(rdx); |
| 1905 } | 1905 } |
| 1906 Handle<Code> ic(isolate()->builtins()->builtin( | 1906 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1907 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1907 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1908 : Builtins::StoreIC_Initialize)); | 1908 : Builtins::StoreIC_Initialize)); |
| 1909 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1909 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1910 | 1910 |
| 1911 // If the assignment ends an initialization block, revert to fast case. | 1911 // If the assignment ends an initialization block, revert to fast case. |
| 1912 if (expr->ends_initialization_block()) { | 1912 if (expr->ends_initialization_block()) { |
| 1913 __ push(rax); // Result of assignment, saved even if not needed. | 1913 __ push(rax); // Result of assignment, saved even if not needed. |
| 1914 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. | 1914 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. |
| 1915 __ CallRuntime(Runtime::kToFastProperties, 1); | 1915 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1916 __ pop(rax); | 1916 __ pop(rax); |
| 1917 __ Drop(1); | 1917 __ Drop(1); |
| 1918 } | 1918 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1937 | 1937 |
| 1938 __ pop(rcx); | 1938 __ pop(rcx); |
| 1939 if (expr->ends_initialization_block()) { | 1939 if (expr->ends_initialization_block()) { |
| 1940 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. | 1940 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. |
| 1941 } else { | 1941 } else { |
| 1942 __ pop(rdx); | 1942 __ pop(rdx); |
| 1943 } | 1943 } |
| 1944 // Record source code position before IC call. | 1944 // Record source code position before IC call. |
| 1945 SetSourcePosition(expr->position()); | 1945 SetSourcePosition(expr->position()); |
| 1946 Handle<Code> ic(isolate()->builtins()->builtin( | 1946 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1947 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 1947 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1948 : Builtins::KeyedStoreIC_Initialize)); | 1948 : Builtins::KeyedStoreIC_Initialize)); |
| 1949 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1949 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1950 | 1950 |
| 1951 // If the assignment ends an initialization block, revert to fast case. | 1951 // If the assignment ends an initialization block, revert to fast case. |
| 1952 if (expr->ends_initialization_block()) { | 1952 if (expr->ends_initialization_block()) { |
| 1953 __ pop(rdx); | 1953 __ pop(rdx); |
| 1954 __ push(rax); // Result of assignment, saved even if not needed. | 1954 __ push(rax); // Result of assignment, saved even if not needed. |
| 1955 __ push(rdx); | 1955 __ push(rdx); |
| 1956 __ CallRuntime(Runtime::kToFastProperties, 1); | 1956 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1957 __ pop(rax); | 1957 __ pop(rax); |
| 1958 } | 1958 } |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2509 Label* if_false = NULL; | 2509 Label* if_false = NULL; |
| 2510 Label* fall_through = NULL; | 2510 Label* fall_through = NULL; |
| 2511 context()->PrepareTest(&materialize_true, &materialize_false, | 2511 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2512 &if_true, &if_false, &fall_through); | 2512 &if_true, &if_false, &fall_through); |
| 2513 | 2513 |
| 2514 // Get the frame pointer for the calling frame. | 2514 // Get the frame pointer for the calling frame. |
| 2515 __ movq(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 2515 __ movq(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 2516 | 2516 |
| 2517 // Skip the arguments adaptor frame if it exists. | 2517 // Skip the arguments adaptor frame if it exists. |
| 2518 Label check_frame_marker; | 2518 Label check_frame_marker; |
| 2519 __ SmiCompare(Operand(rax, StandardFrameConstants::kContextOffset), | 2519 __ Cmp(Operand(rax, StandardFrameConstants::kContextOffset), |
| 2520 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 2520 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 2521 __ j(not_equal, &check_frame_marker); | 2521 __ j(not_equal, &check_frame_marker); |
| 2522 __ movq(rax, Operand(rax, StandardFrameConstants::kCallerFPOffset)); | 2522 __ movq(rax, Operand(rax, StandardFrameConstants::kCallerFPOffset)); |
| 2523 | 2523 |
| 2524 // Check the marker in the calling frame. | 2524 // Check the marker in the calling frame. |
| 2525 __ bind(&check_frame_marker); | 2525 __ bind(&check_frame_marker); |
| 2526 __ SmiCompare(Operand(rax, StandardFrameConstants::kMarkerOffset), | 2526 __ Cmp(Operand(rax, StandardFrameConstants::kMarkerOffset), |
| 2527 Smi::FromInt(StackFrame::CONSTRUCT)); | 2527 Smi::FromInt(StackFrame::CONSTRUCT)); |
| 2528 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2528 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| 2529 Split(equal, if_true, if_false, fall_through); | 2529 Split(equal, if_true, if_false, fall_through); |
| 2530 | 2530 |
| 2531 context()->Plug(if_true, if_false); | 2531 context()->Plug(if_true, if_false); |
| 2532 } | 2532 } |
| 2533 | 2533 |
| 2534 | 2534 |
| 2535 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { | 2535 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { |
| 2536 ASSERT(args->length() == 2); | 2536 ASSERT(args->length() == 2); |
| 2537 | 2537 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2571 | 2571 |
| 2572 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { | 2572 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { |
| 2573 ASSERT(args->length() == 0); | 2573 ASSERT(args->length() == 0); |
| 2574 | 2574 |
| 2575 NearLabel exit; | 2575 NearLabel exit; |
| 2576 // Get the number of formal parameters. | 2576 // Get the number of formal parameters. |
| 2577 __ Move(rax, Smi::FromInt(scope()->num_parameters())); | 2577 __ Move(rax, Smi::FromInt(scope()->num_parameters())); |
| 2578 | 2578 |
| 2579 // Check if the calling frame is an arguments adaptor frame. | 2579 // Check if the calling frame is an arguments adaptor frame. |
| 2580 __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 2580 __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 2581 __ SmiCompare(Operand(rbx, StandardFrameConstants::kContextOffset), | 2581 __ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset), |
| 2582 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 2582 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 2583 __ j(not_equal, &exit); | 2583 __ j(not_equal, &exit); |
| 2584 | 2584 |
| 2585 // Arguments adaptor case: Read the arguments length from the | 2585 // Arguments adaptor case: Read the arguments length from the |
| 2586 // adaptor frame. | 2586 // adaptor frame. |
| 2587 __ movq(rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2587 __ movq(rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 2588 | 2588 |
| 2589 __ bind(&exit); | 2589 __ bind(&exit); |
| 2590 if (FLAG_debug_code) __ AbortIfNotSmi(rax); | 2590 if (FLAG_debug_code) __ AbortIfNotSmi(rax); |
| 2591 context()->Plug(rax); | 2591 context()->Plug(rax); |
| 2592 } | 2592 } |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3017 Label slow_case; | 3017 Label slow_case; |
| 3018 Register object = rax; | 3018 Register object = rax; |
| 3019 Register index_1 = rbx; | 3019 Register index_1 = rbx; |
| 3020 Register index_2 = rcx; | 3020 Register index_2 = rcx; |
| 3021 Register elements = rdi; | 3021 Register elements = rdi; |
| 3022 Register temp = rdx; | 3022 Register temp = rdx; |
| 3023 __ movq(object, Operand(rsp, 2 * kPointerSize)); | 3023 __ movq(object, Operand(rsp, 2 * kPointerSize)); |
| 3024 // Fetch the map and check if array is in fast case. | 3024 // Fetch the map and check if array is in fast case. |
| 3025 // Check that object doesn't require security checks and | 3025 // Check that object doesn't require security checks and |
| 3026 // has no indexed interceptor. | 3026 // has no indexed interceptor. |
| 3027 __ CmpObjectType(object, FIRST_JS_OBJECT_TYPE, temp); | 3027 __ CmpObjectType(object, JS_ARRAY_TYPE, temp); |
| 3028 __ j(below, &slow_case); | 3028 __ j(not_equal, &slow_case); |
| 3029 __ testb(FieldOperand(temp, Map::kBitFieldOffset), | 3029 __ testb(FieldOperand(temp, Map::kBitFieldOffset), |
| 3030 Immediate(KeyedLoadIC::kSlowCaseBitFieldMask)); | 3030 Immediate(KeyedLoadIC::kSlowCaseBitFieldMask)); |
| 3031 __ j(not_zero, &slow_case); | 3031 __ j(not_zero, &slow_case); |
| 3032 | 3032 |
| 3033 // Check the object's elements are in fast case and writable. | 3033 // Check the object's elements are in fast case and writable. |
| 3034 __ movq(elements, FieldOperand(object, JSObject::kElementsOffset)); | 3034 __ movq(elements, FieldOperand(object, JSObject::kElementsOffset)); |
| 3035 __ CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), | 3035 __ CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), |
| 3036 Heap::kFixedArrayMapRootIndex); | 3036 Heap::kFixedArrayMapRootIndex); |
| 3037 __ j(not_equal, &slow_case); | 3037 __ j(not_equal, &slow_case); |
| 3038 | 3038 |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3555 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3555 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3556 Token::ASSIGN); | 3556 Token::ASSIGN); |
| 3557 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3557 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3558 context()->Plug(rax); | 3558 context()->Plug(rax); |
| 3559 } | 3559 } |
| 3560 break; | 3560 break; |
| 3561 case NAMED_PROPERTY: { | 3561 case NAMED_PROPERTY: { |
| 3562 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 3562 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 3563 __ pop(rdx); | 3563 __ pop(rdx); |
| 3564 Handle<Code> ic(isolate()->builtins()->builtin( | 3564 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3565 is_strict() ? Builtins::StoreIC_Initialize_Strict | 3565 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 3566 : Builtins::StoreIC_Initialize)); | 3566 : Builtins::StoreIC_Initialize)); |
| 3567 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3567 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3568 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3568 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3569 if (expr->is_postfix()) { | 3569 if (expr->is_postfix()) { |
| 3570 if (!context()->IsEffect()) { | 3570 if (!context()->IsEffect()) { |
| 3571 context()->PlugTOS(); | 3571 context()->PlugTOS(); |
| 3572 } | 3572 } |
| 3573 } else { | 3573 } else { |
| 3574 context()->Plug(rax); | 3574 context()->Plug(rax); |
| 3575 } | 3575 } |
| 3576 break; | 3576 break; |
| 3577 } | 3577 } |
| 3578 case KEYED_PROPERTY: { | 3578 case KEYED_PROPERTY: { |
| 3579 __ pop(rcx); | 3579 __ pop(rcx); |
| 3580 __ pop(rdx); | 3580 __ pop(rdx); |
| 3581 Handle<Code> ic(isolate()->builtins()->builtin( | 3581 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3582 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 3582 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 3583 : Builtins::KeyedStoreIC_Initialize)); | 3583 : Builtins::KeyedStoreIC_Initialize)); |
| 3584 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3584 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3585 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3585 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3586 if (expr->is_postfix()) { | 3586 if (expr->is_postfix()) { |
| 3587 if (!context()->IsEffect()) { | 3587 if (!context()->IsEffect()) { |
| 3588 context()->PlugTOS(); | 3588 context()->PlugTOS(); |
| 3589 } | 3589 } |
| 3590 } else { | 3590 } else { |
| 3591 context()->Plug(rax); | 3591 context()->Plug(rax); |
| 3592 } | 3592 } |
| 3593 break; | 3593 break; |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3982 __ ret(0); | 3982 __ ret(0); |
| 3983 } | 3983 } |
| 3984 | 3984 |
| 3985 | 3985 |
| 3986 #undef __ | 3986 #undef __ |
| 3987 | 3987 |
| 3988 | 3988 |
| 3989 } } // namespace v8::internal | 3989 } } // namespace v8::internal |
| 3990 | 3990 |
| 3991 #endif // V8_TARGET_ARCH_X64 | 3991 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |