| OLD | NEW | 
|     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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   247     __ CallRuntime(Runtime::kTraceEnter, 0); |   247     __ CallRuntime(Runtime::kTraceEnter, 0); | 
|   248   } |   248   } | 
|   249  |   249  | 
|   250   // Visit the declarations and body unless there is an illegal |   250   // Visit the declarations and body unless there is an illegal | 
|   251   // redeclaration. |   251   // redeclaration. | 
|   252   if (scope()->HasIllegalRedeclaration()) { |   252   if (scope()->HasIllegalRedeclaration()) { | 
|   253     Comment cmnt(masm_, "[ Declarations"); |   253     Comment cmnt(masm_, "[ Declarations"); | 
|   254     scope()->VisitIllegalRedeclaration(this); |   254     scope()->VisitIllegalRedeclaration(this); | 
|   255  |   255  | 
|   256   } else { |   256   } else { | 
|   257     PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS); |   257     PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); | 
|   258     { Comment cmnt(masm_, "[ Declarations"); |   258     { Comment cmnt(masm_, "[ Declarations"); | 
|   259       // For named function expressions, declare the function name as a |   259       // For named function expressions, declare the function name as a | 
|   260       // constant. |   260       // constant. | 
|   261       if (scope()->is_function_scope() && scope()->function() != NULL) { |   261       if (scope()->is_function_scope() && scope()->function() != NULL) { | 
|   262         VariableDeclaration* function = scope()->function(); |   262         VariableDeclaration* function = scope()->function(); | 
|   263         ASSERT(function->proxy()->var()->mode() == CONST || |   263         ASSERT(function->proxy()->var()->mode() == CONST || | 
|   264                function->proxy()->var()->mode() == CONST_HARMONY); |   264                function->proxy()->var()->mode() == CONST_HARMONY); | 
|   265         ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); |   265         ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); | 
|   266         VisitVariableDeclaration(function); |   266         VisitVariableDeclaration(function); | 
|   267       } |   267       } | 
|   268       VisitDeclarations(scope()->declarations()); |   268       VisitDeclarations(scope()->declarations()); | 
|   269     } |   269     } | 
|   270  |   270  | 
|   271     { Comment cmnt(masm_, "[ Stack check"); |   271     { Comment cmnt(masm_, "[ Stack check"); | 
|   272       PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS); |   272       PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); | 
|   273       Label ok; |   273       Label ok; | 
|   274       __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |   274       __ CompareRoot(rsp, Heap::kStackLimitRootIndex); | 
|   275       __ j(above_equal, &ok, Label::kNear); |   275       __ j(above_equal, &ok, Label::kNear); | 
|   276       StackCheckStub stub; |   276       StackCheckStub stub; | 
|   277       __ CallStub(&stub); |   277       __ CallStub(&stub); | 
|   278       __ bind(&ok); |   278       __ bind(&ok); | 
|   279     } |   279     } | 
|   280  |   280  | 
|   281     { Comment cmnt(masm_, "[ Body"); |   281     { Comment cmnt(masm_, "[ Body"); | 
|   282       ASSERT(loop_depth() == 0); |   282       ASSERT(loop_depth() == 0); | 
| (...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1119   __ jmp(&loop); |  1119   __ jmp(&loop); | 
|  1120  |  1120  | 
|  1121   // We got a fixed array in register rax. Iterate through that. |  1121   // We got a fixed array in register rax. Iterate through that. | 
|  1122   Label non_proxy; |  1122   Label non_proxy; | 
|  1123   __ bind(&fixed_array); |  1123   __ bind(&fixed_array); | 
|  1124  |  1124  | 
|  1125   Handle<JSGlobalPropertyCell> cell = |  1125   Handle<JSGlobalPropertyCell> cell = | 
|  1126       isolate()->factory()->NewJSGlobalPropertyCell( |  1126       isolate()->factory()->NewJSGlobalPropertyCell( | 
|  1127           Handle<Object>( |  1127           Handle<Object>( | 
|  1128               Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker))); |  1128               Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker))); | 
|  1129   RecordTypeFeedbackCell(stmt->PrepareId(), cell); |  1129   RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); | 
|  1130   __ LoadHeapObject(rbx, cell); |  1130   __ LoadHeapObject(rbx, cell); | 
|  1131   __ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), |  1131   __ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 
|  1132           Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)); |  1132           Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)); | 
|  1133  |  1133  | 
|  1134   __ Move(rbx, Smi::FromInt(1));  // Smi indicates slow check |  1134   __ Move(rbx, Smi::FromInt(1));  // Smi indicates slow check | 
|  1135   __ movq(rcx, Operand(rsp, 0 * kPointerSize));  // Get enumerated object |  1135   __ movq(rcx, Operand(rsp, 0 * kPointerSize));  // Get enumerated object | 
|  1136   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |  1136   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 
|  1137   __ CmpObjectType(rcx, LAST_JS_PROXY_TYPE, rcx); |  1137   __ CmpObjectType(rcx, LAST_JS_PROXY_TYPE, rcx); | 
|  1138   __ j(above, &non_proxy); |  1138   __ j(above, &non_proxy); | 
|  1139   __ Move(rbx, Smi::FromInt(0));  // Zero indicates proxy |  1139   __ Move(rbx, Smi::FromInt(0));  // Zero indicates proxy | 
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1591         // Fall through. |  1591         // Fall through. | 
|  1592       case ObjectLiteral::Property::COMPUTED: |  1592       case ObjectLiteral::Property::COMPUTED: | 
|  1593         if (key->handle()->IsSymbol()) { |  1593         if (key->handle()->IsSymbol()) { | 
|  1594           if (property->emit_store()) { |  1594           if (property->emit_store()) { | 
|  1595             VisitForAccumulatorValue(value); |  1595             VisitForAccumulatorValue(value); | 
|  1596             __ Move(rcx, key->handle()); |  1596             __ Move(rcx, key->handle()); | 
|  1597             __ movq(rdx, Operand(rsp, 0)); |  1597             __ movq(rdx, Operand(rsp, 0)); | 
|  1598             Handle<Code> ic = is_classic_mode() |  1598             Handle<Code> ic = is_classic_mode() | 
|  1599                 ? isolate()->builtins()->StoreIC_Initialize() |  1599                 ? isolate()->builtins()->StoreIC_Initialize() | 
|  1600                 : isolate()->builtins()->StoreIC_Initialize_Strict(); |  1600                 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 
|  1601             CallIC(ic, RelocInfo::CODE_TARGET, key->id()); |  1601             CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | 
|  1602             PrepareForBailoutForId(key->id(), NO_REGISTERS); |  1602             PrepareForBailoutForId(key->id(), NO_REGISTERS); | 
|  1603           } else { |  1603           } else { | 
|  1604             VisitForEffect(value); |  1604             VisitForEffect(value); | 
|  1605           } |  1605           } | 
|  1606           break; |  1606           break; | 
|  1607         } |  1607         } | 
|  1608         // Fall through. |  1608         // Fall through. | 
|  1609       case ObjectLiteral::Property::PROTOTYPE: |  1609       case ObjectLiteral::Property::PROTOTYPE: | 
|  1610         __ push(Operand(rsp, 0));  // Duplicate receiver. |  1610         __ push(Operand(rsp, 0));  // Duplicate receiver. | 
|  1611         VisitForStackValue(key); |  1611         VisitForStackValue(key); | 
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1861       break; |  1861       break; | 
|  1862   } |  1862   } | 
|  1863 } |  1863 } | 
|  1864  |  1864  | 
|  1865  |  1865  | 
|  1866 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |  1866 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 
|  1867   SetSourcePosition(prop->position()); |  1867   SetSourcePosition(prop->position()); | 
|  1868   Literal* key = prop->key()->AsLiteral(); |  1868   Literal* key = prop->key()->AsLiteral(); | 
|  1869   __ Move(rcx, key->handle()); |  1869   __ Move(rcx, key->handle()); | 
|  1870   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |  1870   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 
|  1871   CallIC(ic, RelocInfo::CODE_TARGET, prop->id()); |  1871   CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 
|  1872 } |  1872 } | 
|  1873  |  1873  | 
|  1874  |  1874  | 
|  1875 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |  1875 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 
|  1876   SetSourcePosition(prop->position()); |  1876   SetSourcePosition(prop->position()); | 
|  1877   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |  1877   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 
|  1878   CallIC(ic, RelocInfo::CODE_TARGET, prop->id()); |  1878   CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 
|  1879 } |  1879 } | 
|  1880  |  1880  | 
|  1881  |  1881  | 
|  1882 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |  1882 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 
|  1883                                               Token::Value op, |  1883                                               Token::Value op, | 
|  1884                                               OverwriteMode mode, |  1884                                               OverwriteMode mode, | 
|  1885                                               Expression* left, |  1885                                               Expression* left, | 
|  1886                                               Expression* right) { |  1886                                               Expression* right) { | 
|  1887   // Do combined smi check of the operands. Left operand is on the |  1887   // Do combined smi check of the operands. Left operand is on the | 
|  1888   // stack (popped into rdx). Right operand is in rax but moved into |  1888   // stack (popped into rdx). Right operand is in rax but moved into | 
|  1889   // rcx to make the shifts easier. |  1889   // rcx to make the shifts easier. | 
|  1890   Label done, stub_call, smi_case; |  1890   Label done, stub_call, smi_case; | 
|  1891   __ pop(rdx); |  1891   __ pop(rdx); | 
|  1892   __ movq(rcx, rax); |  1892   __ movq(rcx, rax); | 
|  1893   __ or_(rax, rdx); |  1893   __ or_(rax, rdx); | 
|  1894   JumpPatchSite patch_site(masm_); |  1894   JumpPatchSite patch_site(masm_); | 
|  1895   patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); |  1895   patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); | 
|  1896  |  1896  | 
|  1897   __ bind(&stub_call); |  1897   __ bind(&stub_call); | 
|  1898   __ movq(rax, rcx); |  1898   __ movq(rax, rcx); | 
|  1899   BinaryOpStub stub(op, mode); |  1899   BinaryOpStub stub(op, mode); | 
|  1900   CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |  1900   CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, | 
 |  1901          expr->BinaryOperationFeedbackId()); | 
|  1901   patch_site.EmitPatchInfo(); |  1902   patch_site.EmitPatchInfo(); | 
|  1902   __ jmp(&done, Label::kNear); |  1903   __ jmp(&done, Label::kNear); | 
|  1903  |  1904  | 
|  1904   __ bind(&smi_case); |  1905   __ bind(&smi_case); | 
|  1905   switch (op) { |  1906   switch (op) { | 
|  1906     case Token::SAR: |  1907     case Token::SAR: | 
|  1907       __ SmiShiftArithmeticRight(rax, rdx, rcx); |  1908       __ SmiShiftArithmeticRight(rax, rdx, rcx); | 
|  1908       break; |  1909       break; | 
|  1909     case Token::SHL: |  1910     case Token::SHL: | 
|  1910       __ SmiShiftLeft(rax, rdx, rcx); |  1911       __ SmiShiftLeft(rax, rdx, rcx); | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|  1939   context()->Plug(rax); |  1940   context()->Plug(rax); | 
|  1940 } |  1941 } | 
|  1941  |  1942  | 
|  1942  |  1943  | 
|  1943 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |  1944 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 
|  1944                                      Token::Value op, |  1945                                      Token::Value op, | 
|  1945                                      OverwriteMode mode) { |  1946                                      OverwriteMode mode) { | 
|  1946   __ pop(rdx); |  1947   __ pop(rdx); | 
|  1947   BinaryOpStub stub(op, mode); |  1948   BinaryOpStub stub(op, mode); | 
|  1948   JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code. |  1949   JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code. | 
|  1949   CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |  1950   CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, | 
 |  1951          expr->BinaryOperationFeedbackId()); | 
|  1950   patch_site.EmitPatchInfo(); |  1952   patch_site.EmitPatchInfo(); | 
|  1951   context()->Plug(rax); |  1953   context()->Plug(rax); | 
|  1952 } |  1954 } | 
|  1953  |  1955  | 
|  1954  |  1956  | 
|  1955 void FullCodeGenerator::EmitAssignment(Expression* expr) { |  1957 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 
|  1956   // Invalid left-hand sides are rewritten to have a 'throw |  1958   // Invalid left-hand sides are rewritten to have a 'throw | 
|  1957   // ReferenceError' on the left-hand side. |  1959   // ReferenceError' on the left-hand side. | 
|  1958   if (!expr->IsValidLeftHandSide()) { |  1960   if (!expr->IsValidLeftHandSide()) { | 
|  1959     VisitForEffect(expr); |  1961     VisitForEffect(expr); | 
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2118   SetSourcePosition(expr->position()); |  2120   SetSourcePosition(expr->position()); | 
|  2119   __ Move(rcx, prop->key()->AsLiteral()->handle()); |  2121   __ Move(rcx, prop->key()->AsLiteral()->handle()); | 
|  2120   if (expr->ends_initialization_block()) { |  2122   if (expr->ends_initialization_block()) { | 
|  2121     __ movq(rdx, Operand(rsp, 0)); |  2123     __ movq(rdx, Operand(rsp, 0)); | 
|  2122   } else { |  2124   } else { | 
|  2123     __ pop(rdx); |  2125     __ pop(rdx); | 
|  2124   } |  2126   } | 
|  2125   Handle<Code> ic = is_classic_mode() |  2127   Handle<Code> ic = is_classic_mode() | 
|  2126       ? isolate()->builtins()->StoreIC_Initialize() |  2128       ? isolate()->builtins()->StoreIC_Initialize() | 
|  2127       : isolate()->builtins()->StoreIC_Initialize_Strict(); |  2129       : isolate()->builtins()->StoreIC_Initialize_Strict(); | 
|  2128   CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |  2130   CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 
|  2129  |  2131  | 
|  2130   // If the assignment ends an initialization block, revert to fast case. |  2132   // If the assignment ends an initialization block, revert to fast case. | 
|  2131   if (expr->ends_initialization_block()) { |  2133   if (expr->ends_initialization_block()) { | 
|  2132     __ push(rax);  // Result of assignment, saved even if not needed. |  2134     __ push(rax);  // Result of assignment, saved even if not needed. | 
|  2133     __ push(Operand(rsp, kPointerSize));  // Receiver is under value. |  2135     __ push(Operand(rsp, kPointerSize));  // Receiver is under value. | 
|  2134     __ CallRuntime(Runtime::kToFastProperties, 1); |  2136     __ CallRuntime(Runtime::kToFastProperties, 1); | 
|  2135     __ pop(rax); |  2137     __ pop(rax); | 
|  2136     __ Drop(1); |  2138     __ Drop(1); | 
|  2137   } |  2139   } | 
|  2138   PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |  2140   PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  2158   if (expr->ends_initialization_block()) { |  2160   if (expr->ends_initialization_block()) { | 
|  2159     __ movq(rdx, Operand(rsp, 0));  // Leave receiver on the stack for later. |  2161     __ movq(rdx, Operand(rsp, 0));  // Leave receiver on the stack for later. | 
|  2160   } else { |  2162   } else { | 
|  2161     __ pop(rdx); |  2163     __ pop(rdx); | 
|  2162   } |  2164   } | 
|  2163   // Record source code position before IC call. |  2165   // Record source code position before IC call. | 
|  2164   SetSourcePosition(expr->position()); |  2166   SetSourcePosition(expr->position()); | 
|  2165   Handle<Code> ic = is_classic_mode() |  2167   Handle<Code> ic = is_classic_mode() | 
|  2166       ? isolate()->builtins()->KeyedStoreIC_Initialize() |  2168       ? isolate()->builtins()->KeyedStoreIC_Initialize() | 
|  2167       : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |  2169       : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 
|  2168   CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |  2170   CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 
|  2169  |  2171  | 
|  2170   // If the assignment ends an initialization block, revert to fast case. |  2172   // If the assignment ends an initialization block, revert to fast case. | 
|  2171   if (expr->ends_initialization_block()) { |  2173   if (expr->ends_initialization_block()) { | 
|  2172     __ pop(rdx); |  2174     __ pop(rdx); | 
|  2173     __ push(rax);  // Result of assignment, saved even if not needed. |  2175     __ push(rax);  // Result of assignment, saved even if not needed. | 
|  2174     __ push(rdx); |  2176     __ push(rdx); | 
|  2175     __ CallRuntime(Runtime::kToFastProperties, 1); |  2177     __ CallRuntime(Runtime::kToFastProperties, 1); | 
|  2176     __ pop(rax); |  2178     __ pop(rax); | 
|  2177   } |  2179   } | 
|  2178  |  2180  | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  2195     VisitForAccumulatorValue(expr->key()); |  2197     VisitForAccumulatorValue(expr->key()); | 
|  2196     __ pop(rdx); |  2198     __ pop(rdx); | 
|  2197     EmitKeyedPropertyLoad(expr); |  2199     EmitKeyedPropertyLoad(expr); | 
|  2198     context()->Plug(rax); |  2200     context()->Plug(rax); | 
|  2199   } |  2201   } | 
|  2200 } |  2202 } | 
|  2201  |  2203  | 
|  2202  |  2204  | 
|  2203 void FullCodeGenerator::CallIC(Handle<Code> code, |  2205 void FullCodeGenerator::CallIC(Handle<Code> code, | 
|  2204                                RelocInfo::Mode rmode, |  2206                                RelocInfo::Mode rmode, | 
|  2205                                unsigned ast_id) { |  2207                                TypeFeedbackId ast_id) { | 
|  2206   ic_total_count_++; |  2208   ic_total_count_++; | 
|  2207   __ call(code, rmode, ast_id); |  2209   __ call(code, rmode, ast_id); | 
|  2208 } |  2210 } | 
|  2209  |  2211  | 
|  2210  |  2212  | 
|  2211 void FullCodeGenerator::EmitCallWithIC(Call* expr, |  2213 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 
|  2212                                        Handle<Object> name, |  2214                                        Handle<Object> name, | 
|  2213                                        RelocInfo::Mode mode) { |  2215                                        RelocInfo::Mode mode) { | 
|  2214   // Code common for calls using the IC. |  2216   // Code common for calls using the IC. | 
|  2215   ZoneList<Expression*>* args = expr->arguments(); |  2217   ZoneList<Expression*>* args = expr->arguments(); | 
|  2216   int arg_count = args->length(); |  2218   int arg_count = args->length(); | 
|  2217   { PreservePositionScope scope(masm()->positions_recorder()); |  2219   { PreservePositionScope scope(masm()->positions_recorder()); | 
|  2218     for (int i = 0; i < arg_count; i++) { |  2220     for (int i = 0; i < arg_count; i++) { | 
|  2219       VisitForStackValue(args->at(i)); |  2221       VisitForStackValue(args->at(i)); | 
|  2220     } |  2222     } | 
|  2221     __ Move(rcx, name); |  2223     __ Move(rcx, name); | 
|  2222   } |  2224   } | 
|  2223   // Record source position for debugger. |  2225   // Record source position for debugger. | 
|  2224   SetSourcePosition(expr->position()); |  2226   SetSourcePosition(expr->position()); | 
|  2225   // Call the IC initialization code. |  2227   // Call the IC initialization code. | 
|  2226   Handle<Code> ic = |  2228   Handle<Code> ic = | 
|  2227       isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |  2229       isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 
|  2228   CallIC(ic, mode, expr->id()); |  2230   CallIC(ic, mode, expr->CallFeedbackId()); | 
|  2229   RecordJSReturnSite(expr); |  2231   RecordJSReturnSite(expr); | 
|  2230   // Restore context register. |  2232   // Restore context register. | 
|  2231   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  2233   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  2232   context()->Plug(rax); |  2234   context()->Plug(rax); | 
|  2233 } |  2235 } | 
|  2234  |  2236  | 
|  2235  |  2237  | 
|  2236 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |  2238 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 
|  2237                                             Expression* key) { |  2239                                             Expression* key) { | 
|  2238   // Load the key. |  2240   // Load the key. | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  2251     for (int i = 0; i < arg_count; i++) { |  2253     for (int i = 0; i < arg_count; i++) { | 
|  2252       VisitForStackValue(args->at(i)); |  2254       VisitForStackValue(args->at(i)); | 
|  2253     } |  2255     } | 
|  2254   } |  2256   } | 
|  2255   // Record source position for debugger. |  2257   // Record source position for debugger. | 
|  2256   SetSourcePosition(expr->position()); |  2258   SetSourcePosition(expr->position()); | 
|  2257   // Call the IC initialization code. |  2259   // Call the IC initialization code. | 
|  2258   Handle<Code> ic = |  2260   Handle<Code> ic = | 
|  2259       isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |  2261       isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 
|  2260   __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize));  // Key. |  2262   __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize));  // Key. | 
|  2261   CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |  2263   CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); | 
|  2262   RecordJSReturnSite(expr); |  2264   RecordJSReturnSite(expr); | 
|  2263   // Restore context register. |  2265   // Restore context register. | 
|  2264   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  2266   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  2265   context()->DropAndPlug(1, rax);  // Drop the key still on the stack. |  2267   context()->DropAndPlug(1, rax);  // Drop the key still on the stack. | 
|  2266 } |  2268 } | 
|  2267  |  2269  | 
|  2268  |  2270  | 
|  2269 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |  2271 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 
|  2270   // Code common for calls using the call stub. |  2272   // Code common for calls using the call stub. | 
|  2271   ZoneList<Expression*>* args = expr->arguments(); |  2273   ZoneList<Expression*>* args = expr->arguments(); | 
|  2272   int arg_count = args->length(); |  2274   int arg_count = args->length(); | 
|  2273   { PreservePositionScope scope(masm()->positions_recorder()); |  2275   { PreservePositionScope scope(masm()->positions_recorder()); | 
|  2274     for (int i = 0; i < arg_count; i++) { |  2276     for (int i = 0; i < arg_count; i++) { | 
|  2275       VisitForStackValue(args->at(i)); |  2277       VisitForStackValue(args->at(i)); | 
|  2276     } |  2278     } | 
|  2277   } |  2279   } | 
|  2278   // Record source position for debugger. |  2280   // Record source position for debugger. | 
|  2279   SetSourcePosition(expr->position()); |  2281   SetSourcePosition(expr->position()); | 
|  2280  |  2282  | 
|  2281   // Record call targets in unoptimized code. |  2283   // Record call targets in unoptimized code. | 
|  2282   flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); |  2284   flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); | 
|  2283   Handle<Object> uninitialized = |  2285   Handle<Object> uninitialized = | 
|  2284       TypeFeedbackCells::UninitializedSentinel(isolate()); |  2286       TypeFeedbackCells::UninitializedSentinel(isolate()); | 
|  2285   Handle<JSGlobalPropertyCell> cell = |  2287   Handle<JSGlobalPropertyCell> cell = | 
|  2286       isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); |  2288       isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | 
|  2287   RecordTypeFeedbackCell(expr->id(), cell); |  2289   RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); | 
|  2288   __ Move(rbx, cell); |  2290   __ Move(rbx, cell); | 
|  2289  |  2291  | 
|  2290   CallFunctionStub stub(arg_count, flags); |  2292   CallFunctionStub stub(arg_count, flags); | 
|  2291   __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |  2293   __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 
|  2292   __ CallStub(&stub, expr->id()); |  2294   __ CallStub(&stub, expr->CallFeedbackId()); | 
|  2293   RecordJSReturnSite(expr); |  2295   RecordJSReturnSite(expr); | 
|  2294   // Restore context register. |  2296   // Restore context register. | 
|  2295   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  2297   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  2296   // Discard the function left on TOS. |  2298   // Discard the function left on TOS. | 
|  2297   context()->DropAndPlug(1, rax); |  2299   context()->DropAndPlug(1, rax); | 
|  2298 } |  2300 } | 
|  2299  |  2301  | 
|  2300  |  2302  | 
|  2301 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |  2303 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 
|  2302   // Push copy of the first argument or undefined if it doesn't exist. |  2304   // Push copy of the first argument or undefined if it doesn't exist. | 
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2461  |  2463  | 
|  2462   // Load function and argument count into rdi and rax. |  2464   // Load function and argument count into rdi and rax. | 
|  2463   __ Set(rax, arg_count); |  2465   __ Set(rax, arg_count); | 
|  2464   __ movq(rdi, Operand(rsp, arg_count * kPointerSize)); |  2466   __ movq(rdi, Operand(rsp, arg_count * kPointerSize)); | 
|  2465  |  2467  | 
|  2466   // Record call targets in unoptimized code, but not in the snapshot. |  2468   // Record call targets in unoptimized code, but not in the snapshot. | 
|  2467   Handle<Object> uninitialized = |  2469   Handle<Object> uninitialized = | 
|  2468       TypeFeedbackCells::UninitializedSentinel(isolate()); |  2470       TypeFeedbackCells::UninitializedSentinel(isolate()); | 
|  2469   Handle<JSGlobalPropertyCell> cell = |  2471   Handle<JSGlobalPropertyCell> cell = | 
|  2470       isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); |  2472       isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | 
|  2471   RecordTypeFeedbackCell(expr->id(), cell); |  2473   RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); | 
|  2472   __ Move(rbx, cell); |  2474   __ Move(rbx, cell); | 
|  2473  |  2475  | 
|  2474   CallConstructStub stub(RECORD_CALL_TARGET); |  2476   CallConstructStub stub(RECORD_CALL_TARGET); | 
|  2475   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |  2477   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 
|  2476   PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |  2478   PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 
|  2477   context()->Plug(rax); |  2479   context()->Plug(rax); | 
|  2478 } |  2480 } | 
|  2479  |  2481  | 
|  2480  |  2482  | 
|  2481 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |  2483 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 
| (...skipping 1317 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3799   for (int i = 0; i < arg_count; i++) { |  3801   for (int i = 0; i < arg_count; i++) { | 
|  3800     VisitForStackValue(args->at(i)); |  3802     VisitForStackValue(args->at(i)); | 
|  3801   } |  3803   } | 
|  3802  |  3804  | 
|  3803   if (expr->is_jsruntime()) { |  3805   if (expr->is_jsruntime()) { | 
|  3804     // Call the JS runtime function using a call IC. |  3806     // Call the JS runtime function using a call IC. | 
|  3805     __ Move(rcx, expr->name()); |  3807     __ Move(rcx, expr->name()); | 
|  3806     RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |  3808     RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 
|  3807     Handle<Code> ic = |  3809     Handle<Code> ic = | 
|  3808         isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |  3810         isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 
|  3809     CallIC(ic, mode, expr->id()); |  3811     CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | 
|  3810     // Restore context register. |  3812     // Restore context register. | 
|  3811     __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  3813     __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  3812   } else { |  3814   } else { | 
|  3813     __ CallRuntime(expr->function(), arg_count); |  3815     __ CallRuntime(expr->function(), arg_count); | 
|  3814   } |  3816   } | 
|  3815   context()->Plug(rax); |  3817   context()->Plug(rax); | 
|  3816 } |  3818 } | 
|  3817  |  3819  | 
|  3818  |  3820  | 
|  3819 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |  3821 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3957   // TODO(svenpanne): Allowing format strings in Comment would be nice here... |  3959   // TODO(svenpanne): Allowing format strings in Comment would be nice here... | 
|  3958   Comment cmt(masm_, comment); |  3960   Comment cmt(masm_, comment); | 
|  3959   bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |  3961   bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 
|  3960   UnaryOverwriteMode overwrite = |  3962   UnaryOverwriteMode overwrite = | 
|  3961       can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |  3963       can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 
|  3962   UnaryOpStub stub(expr->op(), overwrite); |  3964   UnaryOpStub stub(expr->op(), overwrite); | 
|  3963   // UnaryOpStub expects the argument to be in the |  3965   // UnaryOpStub expects the argument to be in the | 
|  3964   // accumulator register rax. |  3966   // accumulator register rax. | 
|  3965   VisitForAccumulatorValue(expr->expression()); |  3967   VisitForAccumulatorValue(expr->expression()); | 
|  3966   SetSourcePosition(expr->position()); |  3968   SetSourcePosition(expr->position()); | 
|  3967   CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |  3969   CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, | 
 |  3970          expr->UnaryOperationFeedbackId()); | 
|  3968   context()->Plug(rax); |  3971   context()->Plug(rax); | 
|  3969 } |  3972 } | 
|  3970  |  3973  | 
|  3971  |  3974  | 
|  3972 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |  3975 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 
|  3973   Comment cmnt(masm_, "[ CountOperation"); |  3976   Comment cmnt(masm_, "[ CountOperation"); | 
|  3974   SetSourcePosition(expr->position()); |  3977   SetSourcePosition(expr->position()); | 
|  3975  |  3978  | 
|  3976   // Invalid left-hand-sides are rewritten to have a 'throw |  3979   // Invalid left-hand-sides are rewritten to have a 'throw | 
|  3977   // ReferenceError' as the left-hand side. |  3980   // ReferenceError' as the left-hand side. | 
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4078   SetSourcePosition(expr->position()); |  4081   SetSourcePosition(expr->position()); | 
|  4079  |  4082  | 
|  4080   // Call stub for +1/-1. |  4083   // Call stub for +1/-1. | 
|  4081   BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); |  4084   BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); | 
|  4082   if (expr->op() == Token::INC) { |  4085   if (expr->op() == Token::INC) { | 
|  4083     __ Move(rdx, Smi::FromInt(1)); |  4086     __ Move(rdx, Smi::FromInt(1)); | 
|  4084   } else { |  4087   } else { | 
|  4085     __ movq(rdx, rax); |  4088     __ movq(rdx, rax); | 
|  4086     __ Move(rax, Smi::FromInt(1)); |  4089     __ Move(rax, Smi::FromInt(1)); | 
|  4087   } |  4090   } | 
|  4088   CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); |  4091   CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountBinOpFeedbackId()); | 
|  4089   patch_site.EmitPatchInfo(); |  4092   patch_site.EmitPatchInfo(); | 
|  4090   __ bind(&done); |  4093   __ bind(&done); | 
|  4091  |  4094  | 
|  4092   // Store the value returned in rax. |  4095   // Store the value returned in rax. | 
|  4093   switch (assign_type) { |  4096   switch (assign_type) { | 
|  4094     case VARIABLE: |  4097     case VARIABLE: | 
|  4095       if (expr->is_postfix()) { |  4098       if (expr->is_postfix()) { | 
|  4096         // Perform the assignment as if via '='. |  4099         // Perform the assignment as if via '='. | 
|  4097         { EffectContext context(this); |  4100         { EffectContext context(this); | 
|  4098           EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |  4101           EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  4112         PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |  4115         PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 
|  4113         context()->Plug(rax); |  4116         context()->Plug(rax); | 
|  4114       } |  4117       } | 
|  4115       break; |  4118       break; | 
|  4116     case NAMED_PROPERTY: { |  4119     case NAMED_PROPERTY: { | 
|  4117       __ Move(rcx, prop->key()->AsLiteral()->handle()); |  4120       __ Move(rcx, prop->key()->AsLiteral()->handle()); | 
|  4118       __ pop(rdx); |  4121       __ pop(rdx); | 
|  4119       Handle<Code> ic = is_classic_mode() |  4122       Handle<Code> ic = is_classic_mode() | 
|  4120           ? isolate()->builtins()->StoreIC_Initialize() |  4123           ? isolate()->builtins()->StoreIC_Initialize() | 
|  4121           : isolate()->builtins()->StoreIC_Initialize_Strict(); |  4124           : isolate()->builtins()->StoreIC_Initialize_Strict(); | 
|  4122       CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |  4125       CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 
|  4123       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |  4126       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 
|  4124       if (expr->is_postfix()) { |  4127       if (expr->is_postfix()) { | 
|  4125         if (!context()->IsEffect()) { |  4128         if (!context()->IsEffect()) { | 
|  4126           context()->PlugTOS(); |  4129           context()->PlugTOS(); | 
|  4127         } |  4130         } | 
|  4128       } else { |  4131       } else { | 
|  4129         context()->Plug(rax); |  4132         context()->Plug(rax); | 
|  4130       } |  4133       } | 
|  4131       break; |  4134       break; | 
|  4132     } |  4135     } | 
|  4133     case KEYED_PROPERTY: { |  4136     case KEYED_PROPERTY: { | 
|  4134       __ pop(rcx); |  4137       __ pop(rcx); | 
|  4135       __ pop(rdx); |  4138       __ pop(rdx); | 
|  4136       Handle<Code> ic = is_classic_mode() |  4139       Handle<Code> ic = is_classic_mode() | 
|  4137           ? isolate()->builtins()->KeyedStoreIC_Initialize() |  4140           ? isolate()->builtins()->KeyedStoreIC_Initialize() | 
|  4138           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |  4141           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 
|  4139       CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |  4142       CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 
|  4140       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |  4143       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 
|  4141       if (expr->is_postfix()) { |  4144       if (expr->is_postfix()) { | 
|  4142         if (!context()->IsEffect()) { |  4145         if (!context()->IsEffect()) { | 
|  4143           context()->PlugTOS(); |  4146           context()->PlugTOS(); | 
|  4144         } |  4147         } | 
|  4145       } else { |  4148       } else { | 
|  4146         context()->Plug(rax); |  4149         context()->Plug(rax); | 
|  4147       } |  4150       } | 
|  4148       break; |  4151       break; | 
|  4149     } |  4152     } | 
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4336         __ or_(rcx, rax); |  4339         __ or_(rcx, rax); | 
|  4337         patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); |  4340         patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); | 
|  4338         __ cmpq(rdx, rax); |  4341         __ cmpq(rdx, rax); | 
|  4339         Split(cc, if_true, if_false, NULL); |  4342         Split(cc, if_true, if_false, NULL); | 
|  4340         __ bind(&slow_case); |  4343         __ bind(&slow_case); | 
|  4341       } |  4344       } | 
|  4342  |  4345  | 
|  4343       // Record position and call the compare IC. |  4346       // Record position and call the compare IC. | 
|  4344       SetSourcePosition(expr->position()); |  4347       SetSourcePosition(expr->position()); | 
|  4345       Handle<Code> ic = CompareIC::GetUninitialized(op); |  4348       Handle<Code> ic = CompareIC::GetUninitialized(op); | 
|  4346       CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |  4349       CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 
|  4347       patch_site.EmitPatchInfo(); |  4350       patch_site.EmitPatchInfo(); | 
|  4348  |  4351  | 
|  4349       PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |  4352       PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 
|  4350       __ testq(rax, rax); |  4353       __ testq(rax, rax); | 
|  4351       Split(cc, if_true, if_false, fall_through); |  4354       Split(cc, if_true, if_false, fall_through); | 
|  4352     } |  4355     } | 
|  4353   } |  4356   } | 
|  4354  |  4357  | 
|  4355   // Convert the result of the comparison into one expected for this |  4358   // Convert the result of the comparison into one expected for this | 
|  4356   // expression's context. |  4359   // expression's context. | 
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4536   *context_length = 0; |  4539   *context_length = 0; | 
|  4537   return previous_; |  4540   return previous_; | 
|  4538 } |  4541 } | 
|  4539  |  4542  | 
|  4540  |  4543  | 
|  4541 #undef __ |  4544 #undef __ | 
|  4542  |  4545  | 
|  4543 } }  // namespace v8::internal |  4546 } }  // namespace v8::internal | 
|  4544  |  4547  | 
|  4545 #endif  // V8_TARGET_ARCH_X64 |  4548 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW |