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 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 __ CallRuntime(Runtime::kTraceEnter, 0); | 252 __ CallRuntime(Runtime::kTraceEnter, 0); |
253 } | 253 } |
254 | 254 |
255 // Visit the declarations and body unless there is an illegal | 255 // Visit the declarations and body unless there is an illegal |
256 // redeclaration. | 256 // redeclaration. |
257 if (scope()->HasIllegalRedeclaration()) { | 257 if (scope()->HasIllegalRedeclaration()) { |
258 Comment cmnt(masm_, "[ Declarations"); | 258 Comment cmnt(masm_, "[ Declarations"); |
259 scope()->VisitIllegalRedeclaration(this); | 259 scope()->VisitIllegalRedeclaration(this); |
260 | 260 |
261 } else { | 261 } else { |
262 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS); | 262 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); |
263 { Comment cmnt(masm_, "[ Declarations"); | 263 { Comment cmnt(masm_, "[ Declarations"); |
264 // For named function expressions, declare the function name as a | 264 // For named function expressions, declare the function name as a |
265 // constant. | 265 // constant. |
266 if (scope()->is_function_scope() && scope()->function() != NULL) { | 266 if (scope()->is_function_scope() && scope()->function() != NULL) { |
267 VariableDeclaration* function = scope()->function(); | 267 VariableDeclaration* function = scope()->function(); |
268 ASSERT(function->proxy()->var()->mode() == CONST || | 268 ASSERT(function->proxy()->var()->mode() == CONST || |
269 function->proxy()->var()->mode() == CONST_HARMONY); | 269 function->proxy()->var()->mode() == CONST_HARMONY); |
270 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); | 270 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); |
271 VisitVariableDeclaration(function); | 271 VisitVariableDeclaration(function); |
272 } | 272 } |
273 VisitDeclarations(scope()->declarations()); | 273 VisitDeclarations(scope()->declarations()); |
274 } | 274 } |
275 | 275 |
276 { Comment cmnt(masm_, "[ Stack check"); | 276 { Comment cmnt(masm_, "[ Stack check"); |
277 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS); | 277 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); |
278 Label ok; | 278 Label ok; |
279 ExternalReference stack_limit = | 279 ExternalReference stack_limit = |
280 ExternalReference::address_of_stack_limit(isolate()); | 280 ExternalReference::address_of_stack_limit(isolate()); |
281 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 281 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
282 __ j(above_equal, &ok, Label::kNear); | 282 __ j(above_equal, &ok, Label::kNear); |
283 StackCheckStub stub; | 283 StackCheckStub stub; |
284 __ CallStub(&stub); | 284 __ CallStub(&stub); |
285 __ bind(&ok); | 285 __ bind(&ok); |
286 } | 286 } |
287 | 287 |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 __ jmp(&loop); | 1102 __ jmp(&loop); |
1103 | 1103 |
1104 // We got a fixed array in register eax. Iterate through that. | 1104 // We got a fixed array in register eax. Iterate through that. |
1105 Label non_proxy; | 1105 Label non_proxy; |
1106 __ bind(&fixed_array); | 1106 __ bind(&fixed_array); |
1107 | 1107 |
1108 Handle<JSGlobalPropertyCell> cell = | 1108 Handle<JSGlobalPropertyCell> cell = |
1109 isolate()->factory()->NewJSGlobalPropertyCell( | 1109 isolate()->factory()->NewJSGlobalPropertyCell( |
1110 Handle<Object>( | 1110 Handle<Object>( |
1111 Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker))); | 1111 Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker))); |
1112 RecordTypeFeedbackCell(stmt->PrepareId(), cell); | 1112 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); |
1113 __ LoadHeapObject(ebx, cell); | 1113 __ LoadHeapObject(ebx, cell); |
1114 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), | 1114 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), |
1115 Immediate(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); | 1115 Immediate(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); |
1116 | 1116 |
1117 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check | 1117 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check |
1118 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object | 1118 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object |
1119 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 1119 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
1120 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); | 1120 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); |
1121 __ j(above, &non_proxy); | 1121 __ j(above, &non_proxy); |
1122 __ mov(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy | 1122 __ mov(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1572 // Fall through. | 1572 // Fall through. |
1573 case ObjectLiteral::Property::COMPUTED: | 1573 case ObjectLiteral::Property::COMPUTED: |
1574 if (key->handle()->IsSymbol()) { | 1574 if (key->handle()->IsSymbol()) { |
1575 if (property->emit_store()) { | 1575 if (property->emit_store()) { |
1576 VisitForAccumulatorValue(value); | 1576 VisitForAccumulatorValue(value); |
1577 __ mov(ecx, Immediate(key->handle())); | 1577 __ mov(ecx, Immediate(key->handle())); |
1578 __ mov(edx, Operand(esp, 0)); | 1578 __ mov(edx, Operand(esp, 0)); |
1579 Handle<Code> ic = is_classic_mode() | 1579 Handle<Code> ic = is_classic_mode() |
1580 ? isolate()->builtins()->StoreIC_Initialize() | 1580 ? isolate()->builtins()->StoreIC_Initialize() |
1581 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 1581 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
1582 CallIC(ic, RelocInfo::CODE_TARGET, key->id()); | 1582 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); |
1583 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1583 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1584 } else { | 1584 } else { |
1585 VisitForEffect(value); | 1585 VisitForEffect(value); |
1586 } | 1586 } |
1587 break; | 1587 break; |
1588 } | 1588 } |
1589 // Fall through. | 1589 // Fall through. |
1590 case ObjectLiteral::Property::PROTOTYPE: | 1590 case ObjectLiteral::Property::PROTOTYPE: |
1591 __ push(Operand(esp, 0)); // Duplicate receiver. | 1591 __ push(Operand(esp, 0)); // Duplicate receiver. |
1592 VisitForStackValue(key); | 1592 VisitForStackValue(key); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1844 } | 1844 } |
1845 } | 1845 } |
1846 | 1846 |
1847 | 1847 |
1848 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1848 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1849 SetSourcePosition(prop->position()); | 1849 SetSourcePosition(prop->position()); |
1850 Literal* key = prop->key()->AsLiteral(); | 1850 Literal* key = prop->key()->AsLiteral(); |
1851 ASSERT(!key->handle()->IsSmi()); | 1851 ASSERT(!key->handle()->IsSmi()); |
1852 __ mov(ecx, Immediate(key->handle())); | 1852 __ mov(ecx, Immediate(key->handle())); |
1853 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1853 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1854 CallIC(ic, RelocInfo::CODE_TARGET, prop->id()); | 1854 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); |
1855 } | 1855 } |
1856 | 1856 |
1857 | 1857 |
1858 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1858 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1859 SetSourcePosition(prop->position()); | 1859 SetSourcePosition(prop->position()); |
1860 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1860 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
1861 CallIC(ic, RelocInfo::CODE_TARGET, prop->id()); | 1861 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); |
1862 } | 1862 } |
1863 | 1863 |
1864 | 1864 |
1865 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1865 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
1866 Token::Value op, | 1866 Token::Value op, |
1867 OverwriteMode mode, | 1867 OverwriteMode mode, |
1868 Expression* left, | 1868 Expression* left, |
1869 Expression* right) { | 1869 Expression* right) { |
1870 // Do combined smi check of the operands. Left operand is on the | 1870 // Do combined smi check of the operands. Left operand is on the |
1871 // stack. Right operand is in eax. | 1871 // stack. Right operand is in eax. |
1872 Label smi_case, done, stub_call; | 1872 Label smi_case, done, stub_call; |
1873 __ pop(edx); | 1873 __ pop(edx); |
1874 __ mov(ecx, eax); | 1874 __ mov(ecx, eax); |
1875 __ or_(eax, edx); | 1875 __ or_(eax, edx); |
1876 JumpPatchSite patch_site(masm_); | 1876 JumpPatchSite patch_site(masm_); |
1877 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); | 1877 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); |
1878 | 1878 |
1879 __ bind(&stub_call); | 1879 __ bind(&stub_call); |
1880 __ mov(eax, ecx); | 1880 __ mov(eax, ecx); |
1881 BinaryOpStub stub(op, mode); | 1881 BinaryOpStub stub(op, mode); |
1882 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1882 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, |
| 1883 expr->BinaryOperationFeedbackId()); |
1883 patch_site.EmitPatchInfo(); | 1884 patch_site.EmitPatchInfo(); |
1884 __ jmp(&done, Label::kNear); | 1885 __ jmp(&done, Label::kNear); |
1885 | 1886 |
1886 // Smi case. | 1887 // Smi case. |
1887 __ bind(&smi_case); | 1888 __ bind(&smi_case); |
1888 __ mov(eax, edx); // Copy left operand in case of a stub call. | 1889 __ mov(eax, edx); // Copy left operand in case of a stub call. |
1889 | 1890 |
1890 switch (op) { | 1891 switch (op) { |
1891 case Token::SAR: | 1892 case Token::SAR: |
1892 __ SmiUntag(eax); | 1893 __ SmiUntag(eax); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1957 context()->Plug(eax); | 1958 context()->Plug(eax); |
1958 } | 1959 } |
1959 | 1960 |
1960 | 1961 |
1961 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 1962 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
1962 Token::Value op, | 1963 Token::Value op, |
1963 OverwriteMode mode) { | 1964 OverwriteMode mode) { |
1964 __ pop(edx); | 1965 __ pop(edx); |
1965 BinaryOpStub stub(op, mode); | 1966 BinaryOpStub stub(op, mode); |
1966 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 1967 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
1967 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1968 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, |
| 1969 expr->BinaryOperationFeedbackId()); |
1968 patch_site.EmitPatchInfo(); | 1970 patch_site.EmitPatchInfo(); |
1969 context()->Plug(eax); | 1971 context()->Plug(eax); |
1970 } | 1972 } |
1971 | 1973 |
1972 | 1974 |
1973 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 1975 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
1974 // Invalid left-hand sides are rewritten to have a 'throw | 1976 // Invalid left-hand sides are rewritten to have a 'throw |
1975 // ReferenceError' on the left-hand side. | 1977 // ReferenceError' on the left-hand side. |
1976 if (!expr->IsValidLeftHandSide()) { | 1978 if (!expr->IsValidLeftHandSide()) { |
1977 VisitForEffect(expr); | 1979 VisitForEffect(expr); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2140 SetSourcePosition(expr->position()); | 2142 SetSourcePosition(expr->position()); |
2141 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 2143 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
2142 if (expr->ends_initialization_block()) { | 2144 if (expr->ends_initialization_block()) { |
2143 __ mov(edx, Operand(esp, 0)); | 2145 __ mov(edx, Operand(esp, 0)); |
2144 } else { | 2146 } else { |
2145 __ pop(edx); | 2147 __ pop(edx); |
2146 } | 2148 } |
2147 Handle<Code> ic = is_classic_mode() | 2149 Handle<Code> ic = is_classic_mode() |
2148 ? isolate()->builtins()->StoreIC_Initialize() | 2150 ? isolate()->builtins()->StoreIC_Initialize() |
2149 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 2151 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
2150 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2152 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); |
2151 | 2153 |
2152 // If the assignment ends an initialization block, revert to fast case. | 2154 // If the assignment ends an initialization block, revert to fast case. |
2153 if (expr->ends_initialization_block()) { | 2155 if (expr->ends_initialization_block()) { |
2154 __ push(eax); // Result of assignment, saved even if not needed. | 2156 __ push(eax); // Result of assignment, saved even if not needed. |
2155 __ push(Operand(esp, kPointerSize)); // Receiver is under value. | 2157 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
2156 __ CallRuntime(Runtime::kToFastProperties, 1); | 2158 __ CallRuntime(Runtime::kToFastProperties, 1); |
2157 __ pop(eax); | 2159 __ pop(eax); |
2158 __ Drop(1); | 2160 __ Drop(1); |
2159 } | 2161 } |
2160 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2162 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
(...skipping 22 matching lines...) Expand all Loading... |
2183 if (expr->ends_initialization_block()) { | 2185 if (expr->ends_initialization_block()) { |
2184 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. | 2186 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. |
2185 } else { | 2187 } else { |
2186 __ pop(edx); | 2188 __ pop(edx); |
2187 } | 2189 } |
2188 // Record source code position before IC call. | 2190 // Record source code position before IC call. |
2189 SetSourcePosition(expr->position()); | 2191 SetSourcePosition(expr->position()); |
2190 Handle<Code> ic = is_classic_mode() | 2192 Handle<Code> ic = is_classic_mode() |
2191 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2193 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2192 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2194 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2193 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2195 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); |
2194 | 2196 |
2195 // If the assignment ends an initialization block, revert to fast case. | 2197 // If the assignment ends an initialization block, revert to fast case. |
2196 if (expr->ends_initialization_block()) { | 2198 if (expr->ends_initialization_block()) { |
2197 __ pop(edx); | 2199 __ pop(edx); |
2198 __ push(eax); // Result of assignment, saved even if not needed. | 2200 __ push(eax); // Result of assignment, saved even if not needed. |
2199 __ push(edx); | 2201 __ push(edx); |
2200 __ CallRuntime(Runtime::kToFastProperties, 1); | 2202 __ CallRuntime(Runtime::kToFastProperties, 1); |
2201 __ pop(eax); | 2203 __ pop(eax); |
2202 } | 2204 } |
2203 | 2205 |
(...skipping 18 matching lines...) Expand all Loading... |
2222 __ pop(edx); // Object. | 2224 __ pop(edx); // Object. |
2223 __ mov(ecx, result_register()); // Key. | 2225 __ mov(ecx, result_register()); // Key. |
2224 EmitKeyedPropertyLoad(expr); | 2226 EmitKeyedPropertyLoad(expr); |
2225 context()->Plug(eax); | 2227 context()->Plug(eax); |
2226 } | 2228 } |
2227 } | 2229 } |
2228 | 2230 |
2229 | 2231 |
2230 void FullCodeGenerator::CallIC(Handle<Code> code, | 2232 void FullCodeGenerator::CallIC(Handle<Code> code, |
2231 RelocInfo::Mode rmode, | 2233 RelocInfo::Mode rmode, |
2232 unsigned ast_id) { | 2234 TypeFeedbackId ast_id) { |
2233 ic_total_count_++; | 2235 ic_total_count_++; |
2234 __ call(code, rmode, ast_id); | 2236 __ call(code, rmode, ast_id); |
2235 } | 2237 } |
2236 | 2238 |
2237 | 2239 |
2238 | 2240 |
2239 | 2241 |
2240 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2242 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
2241 Handle<Object> name, | 2243 Handle<Object> name, |
2242 RelocInfo::Mode mode) { | 2244 RelocInfo::Mode mode) { |
2243 // Code common for calls using the IC. | 2245 // Code common for calls using the IC. |
2244 ZoneList<Expression*>* args = expr->arguments(); | 2246 ZoneList<Expression*>* args = expr->arguments(); |
2245 int arg_count = args->length(); | 2247 int arg_count = args->length(); |
2246 { PreservePositionScope scope(masm()->positions_recorder()); | 2248 { PreservePositionScope scope(masm()->positions_recorder()); |
2247 for (int i = 0; i < arg_count; i++) { | 2249 for (int i = 0; i < arg_count; i++) { |
2248 VisitForStackValue(args->at(i)); | 2250 VisitForStackValue(args->at(i)); |
2249 } | 2251 } |
2250 __ Set(ecx, Immediate(name)); | 2252 __ Set(ecx, Immediate(name)); |
2251 } | 2253 } |
2252 // Record source position of the IC call. | 2254 // Record source position of the IC call. |
2253 SetSourcePosition(expr->position()); | 2255 SetSourcePosition(expr->position()); |
2254 Handle<Code> ic = | 2256 Handle<Code> ic = |
2255 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2257 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
2256 CallIC(ic, mode, expr->id()); | 2258 CallIC(ic, mode, expr->CallFeedbackId()); |
2257 RecordJSReturnSite(expr); | 2259 RecordJSReturnSite(expr); |
2258 // Restore context register. | 2260 // Restore context register. |
2259 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2261 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2260 context()->Plug(eax); | 2262 context()->Plug(eax); |
2261 } | 2263 } |
2262 | 2264 |
2263 | 2265 |
2264 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2266 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2265 Expression* key) { | 2267 Expression* key) { |
2266 // Load the key. | 2268 // Load the key. |
(...skipping 11 matching lines...) Expand all Loading... |
2278 { PreservePositionScope scope(masm()->positions_recorder()); | 2280 { PreservePositionScope scope(masm()->positions_recorder()); |
2279 for (int i = 0; i < arg_count; i++) { | 2281 for (int i = 0; i < arg_count; i++) { |
2280 VisitForStackValue(args->at(i)); | 2282 VisitForStackValue(args->at(i)); |
2281 } | 2283 } |
2282 } | 2284 } |
2283 // Record source position of the IC call. | 2285 // Record source position of the IC call. |
2284 SetSourcePosition(expr->position()); | 2286 SetSourcePosition(expr->position()); |
2285 Handle<Code> ic = | 2287 Handle<Code> ic = |
2286 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2288 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
2287 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. | 2289 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. |
2288 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2290 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); |
2289 RecordJSReturnSite(expr); | 2291 RecordJSReturnSite(expr); |
2290 // Restore context register. | 2292 // Restore context register. |
2291 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2293 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2292 context()->DropAndPlug(1, eax); // Drop the key still on the stack. | 2294 context()->DropAndPlug(1, eax); // Drop the key still on the stack. |
2293 } | 2295 } |
2294 | 2296 |
2295 | 2297 |
2296 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2298 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
2297 // Code common for calls using the call stub. | 2299 // Code common for calls using the call stub. |
2298 ZoneList<Expression*>* args = expr->arguments(); | 2300 ZoneList<Expression*>* args = expr->arguments(); |
2299 int arg_count = args->length(); | 2301 int arg_count = args->length(); |
2300 { PreservePositionScope scope(masm()->positions_recorder()); | 2302 { PreservePositionScope scope(masm()->positions_recorder()); |
2301 for (int i = 0; i < arg_count; i++) { | 2303 for (int i = 0; i < arg_count; i++) { |
2302 VisitForStackValue(args->at(i)); | 2304 VisitForStackValue(args->at(i)); |
2303 } | 2305 } |
2304 } | 2306 } |
2305 // Record source position for debugger. | 2307 // Record source position for debugger. |
2306 SetSourcePosition(expr->position()); | 2308 SetSourcePosition(expr->position()); |
2307 | 2309 |
2308 // Record call targets in unoptimized code. | 2310 // Record call targets in unoptimized code. |
2309 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); | 2311 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); |
2310 Handle<Object> uninitialized = | 2312 Handle<Object> uninitialized = |
2311 TypeFeedbackCells::UninitializedSentinel(isolate()); | 2313 TypeFeedbackCells::UninitializedSentinel(isolate()); |
2312 Handle<JSGlobalPropertyCell> cell = | 2314 Handle<JSGlobalPropertyCell> cell = |
2313 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | 2315 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); |
2314 RecordTypeFeedbackCell(expr->id(), cell); | 2316 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); |
2315 __ mov(ebx, cell); | 2317 __ mov(ebx, cell); |
2316 | 2318 |
2317 CallFunctionStub stub(arg_count, flags); | 2319 CallFunctionStub stub(arg_count, flags); |
2318 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2320 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
2319 __ CallStub(&stub, expr->id()); | 2321 __ CallStub(&stub, expr->CallFeedbackId()); |
2320 | 2322 |
2321 RecordJSReturnSite(expr); | 2323 RecordJSReturnSite(expr); |
2322 // Restore context register. | 2324 // Restore context register. |
2323 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2325 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2324 context()->DropAndPlug(1, eax); | 2326 context()->DropAndPlug(1, eax); |
2325 } | 2327 } |
2326 | 2328 |
2327 | 2329 |
2328 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2330 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
2329 // Push copy of the first argument or undefined if it doesn't exist. | 2331 // Push copy of the first argument or undefined if it doesn't exist. |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2489 | 2491 |
2490 // Load function and argument count into edi and eax. | 2492 // Load function and argument count into edi and eax. |
2491 __ Set(eax, Immediate(arg_count)); | 2493 __ Set(eax, Immediate(arg_count)); |
2492 __ mov(edi, Operand(esp, arg_count * kPointerSize)); | 2494 __ mov(edi, Operand(esp, arg_count * kPointerSize)); |
2493 | 2495 |
2494 // Record call targets in unoptimized code. | 2496 // Record call targets in unoptimized code. |
2495 Handle<Object> uninitialized = | 2497 Handle<Object> uninitialized = |
2496 TypeFeedbackCells::UninitializedSentinel(isolate()); | 2498 TypeFeedbackCells::UninitializedSentinel(isolate()); |
2497 Handle<JSGlobalPropertyCell> cell = | 2499 Handle<JSGlobalPropertyCell> cell = |
2498 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | 2500 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); |
2499 RecordTypeFeedbackCell(expr->id(), cell); | 2501 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); |
2500 __ mov(ebx, cell); | 2502 __ mov(ebx, cell); |
2501 | 2503 |
2502 CallConstructStub stub(RECORD_CALL_TARGET); | 2504 CallConstructStub stub(RECORD_CALL_TARGET); |
2503 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 2505 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
2504 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2506 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2505 context()->Plug(eax); | 2507 context()->Plug(eax); |
2506 } | 2508 } |
2507 | 2509 |
2508 | 2510 |
2509 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2511 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3807 for (int i = 0; i < arg_count; i++) { | 3809 for (int i = 0; i < arg_count; i++) { |
3808 VisitForStackValue(args->at(i)); | 3810 VisitForStackValue(args->at(i)); |
3809 } | 3811 } |
3810 | 3812 |
3811 if (expr->is_jsruntime()) { | 3813 if (expr->is_jsruntime()) { |
3812 // Call the JS runtime function via a call IC. | 3814 // Call the JS runtime function via a call IC. |
3813 __ Set(ecx, Immediate(expr->name())); | 3815 __ Set(ecx, Immediate(expr->name())); |
3814 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 3816 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
3815 Handle<Code> ic = | 3817 Handle<Code> ic = |
3816 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 3818 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
3817 CallIC(ic, mode, expr->id()); | 3819 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
3818 // Restore context register. | 3820 // Restore context register. |
3819 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 3821 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
3820 } else { | 3822 } else { |
3821 // Call the C runtime function. | 3823 // Call the C runtime function. |
3822 __ CallRuntime(expr->function(), arg_count); | 3824 __ CallRuntime(expr->function(), arg_count); |
3823 } | 3825 } |
3824 context()->Plug(eax); | 3826 context()->Plug(eax); |
3825 } | 3827 } |
3826 | 3828 |
3827 | 3829 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3965 const char* comment) { | 3967 const char* comment) { |
3966 Comment cmt(masm_, comment); | 3968 Comment cmt(masm_, comment); |
3967 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 3969 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
3968 UnaryOverwriteMode overwrite = | 3970 UnaryOverwriteMode overwrite = |
3969 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 3971 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
3970 UnaryOpStub stub(expr->op(), overwrite); | 3972 UnaryOpStub stub(expr->op(), overwrite); |
3971 // UnaryOpStub expects the argument to be in the | 3973 // UnaryOpStub expects the argument to be in the |
3972 // accumulator register eax. | 3974 // accumulator register eax. |
3973 VisitForAccumulatorValue(expr->expression()); | 3975 VisitForAccumulatorValue(expr->expression()); |
3974 SetSourcePosition(expr->position()); | 3976 SetSourcePosition(expr->position()); |
3975 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 3977 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, |
| 3978 expr->UnaryOperationFeedbackId()); |
3976 context()->Plug(eax); | 3979 context()->Plug(eax); |
3977 } | 3980 } |
3978 | 3981 |
3979 | 3982 |
3980 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 3983 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
3981 Comment cmnt(masm_, "[ CountOperation"); | 3984 Comment cmnt(masm_, "[ CountOperation"); |
3982 SetSourcePosition(expr->position()); | 3985 SetSourcePosition(expr->position()); |
3983 | 3986 |
3984 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' | 3987 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' |
3985 // as the left-hand side. | 3988 // as the left-hand side. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4086 } | 4089 } |
4087 } | 4090 } |
4088 | 4091 |
4089 // Record position before stub call. | 4092 // Record position before stub call. |
4090 SetSourcePosition(expr->position()); | 4093 SetSourcePosition(expr->position()); |
4091 | 4094 |
4092 // Call stub for +1/-1. | 4095 // Call stub for +1/-1. |
4093 __ mov(edx, eax); | 4096 __ mov(edx, eax); |
4094 __ mov(eax, Immediate(Smi::FromInt(1))); | 4097 __ mov(eax, Immediate(Smi::FromInt(1))); |
4095 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); | 4098 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); |
4096 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); | 4099 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountBinOpFeedbackId()); |
4097 patch_site.EmitPatchInfo(); | 4100 patch_site.EmitPatchInfo(); |
4098 __ bind(&done); | 4101 __ bind(&done); |
4099 | 4102 |
4100 // Store the value returned in eax. | 4103 // Store the value returned in eax. |
4101 switch (assign_type) { | 4104 switch (assign_type) { |
4102 case VARIABLE: | 4105 case VARIABLE: |
4103 if (expr->is_postfix()) { | 4106 if (expr->is_postfix()) { |
4104 // Perform the assignment as if via '='. | 4107 // Perform the assignment as if via '='. |
4105 { EffectContext context(this); | 4108 { EffectContext context(this); |
4106 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4109 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
(...skipping 13 matching lines...) Expand all Loading... |
4120 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4123 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4121 context()->Plug(eax); | 4124 context()->Plug(eax); |
4122 } | 4125 } |
4123 break; | 4126 break; |
4124 case NAMED_PROPERTY: { | 4127 case NAMED_PROPERTY: { |
4125 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 4128 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
4126 __ pop(edx); | 4129 __ pop(edx); |
4127 Handle<Code> ic = is_classic_mode() | 4130 Handle<Code> ic = is_classic_mode() |
4128 ? isolate()->builtins()->StoreIC_Initialize() | 4131 ? isolate()->builtins()->StoreIC_Initialize() |
4129 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 4132 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
4130 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4133 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); |
4131 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4134 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4132 if (expr->is_postfix()) { | 4135 if (expr->is_postfix()) { |
4133 if (!context()->IsEffect()) { | 4136 if (!context()->IsEffect()) { |
4134 context()->PlugTOS(); | 4137 context()->PlugTOS(); |
4135 } | 4138 } |
4136 } else { | 4139 } else { |
4137 context()->Plug(eax); | 4140 context()->Plug(eax); |
4138 } | 4141 } |
4139 break; | 4142 break; |
4140 } | 4143 } |
4141 case KEYED_PROPERTY: { | 4144 case KEYED_PROPERTY: { |
4142 __ pop(ecx); | 4145 __ pop(ecx); |
4143 __ pop(edx); | 4146 __ pop(edx); |
4144 Handle<Code> ic = is_classic_mode() | 4147 Handle<Code> ic = is_classic_mode() |
4145 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4148 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
4146 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4149 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
4147 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4150 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); |
4148 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4151 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4149 if (expr->is_postfix()) { | 4152 if (expr->is_postfix()) { |
4150 // Result is on the stack | 4153 // Result is on the stack |
4151 if (!context()->IsEffect()) { | 4154 if (!context()->IsEffect()) { |
4152 context()->PlugTOS(); | 4155 context()->PlugTOS(); |
4153 } | 4156 } |
4154 } else { | 4157 } else { |
4155 context()->Plug(eax); | 4158 context()->Plug(eax); |
4156 } | 4159 } |
4157 break; | 4160 break; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4345 __ or_(ecx, eax); | 4348 __ or_(ecx, eax); |
4346 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 4349 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
4347 __ cmp(edx, eax); | 4350 __ cmp(edx, eax); |
4348 Split(cc, if_true, if_false, NULL); | 4351 Split(cc, if_true, if_false, NULL); |
4349 __ bind(&slow_case); | 4352 __ bind(&slow_case); |
4350 } | 4353 } |
4351 | 4354 |
4352 // Record position and call the compare IC. | 4355 // Record position and call the compare IC. |
4353 SetSourcePosition(expr->position()); | 4356 SetSourcePosition(expr->position()); |
4354 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4357 Handle<Code> ic = CompareIC::GetUninitialized(op); |
4355 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4358 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); |
4356 patch_site.EmitPatchInfo(); | 4359 patch_site.EmitPatchInfo(); |
4357 | 4360 |
4358 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4361 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4359 __ test(eax, eax); | 4362 __ test(eax, eax); |
4360 Split(cc, if_true, if_false, fall_through); | 4363 Split(cc, if_true, if_false, fall_through); |
4361 } | 4364 } |
4362 } | 4365 } |
4363 | 4366 |
4364 // Convert the result of the comparison into one expected for this | 4367 // Convert the result of the comparison into one expected for this |
4365 // expression's context. | 4368 // expression's context. |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4541 *stack_depth = 0; | 4544 *stack_depth = 0; |
4542 *context_length = 0; | 4545 *context_length = 0; |
4543 return previous_; | 4546 return previous_; |
4544 } | 4547 } |
4545 | 4548 |
4546 #undef __ | 4549 #undef __ |
4547 | 4550 |
4548 } } // namespace v8::internal | 4551 } } // namespace v8::internal |
4549 | 4552 |
4550 #endif // V8_TARGET_ARCH_IA32 | 4553 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |