Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(290)

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 10831172: Introduced TypeFeedbackId and BailoutId types. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Incorporated review feedback. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/deoptimizer-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/deoptimizer-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698