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

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

Powered by Google App Engine
This is Rietveld 408576698