| 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 |