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 |