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 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 __ CallRuntime(Runtime::kTraceEnter, 0); | 265 __ CallRuntime(Runtime::kTraceEnter, 0); |
266 } | 266 } |
267 | 267 |
268 // Visit the declarations and body unless there is an illegal | 268 // Visit the declarations and body unless there is an illegal |
269 // redeclaration. | 269 // redeclaration. |
270 if (scope()->HasIllegalRedeclaration()) { | 270 if (scope()->HasIllegalRedeclaration()) { |
271 Comment cmnt(masm_, "[ Declarations"); | 271 Comment cmnt(masm_, "[ Declarations"); |
272 scope()->VisitIllegalRedeclaration(this); | 272 scope()->VisitIllegalRedeclaration(this); |
273 | 273 |
274 } else { | 274 } else { |
275 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS); | 275 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); |
276 { Comment cmnt(masm_, "[ Declarations"); | 276 { Comment cmnt(masm_, "[ Declarations"); |
277 // For named function expressions, declare the function name as a | 277 // For named function expressions, declare the function name as a |
278 // constant. | 278 // constant. |
279 if (scope()->is_function_scope() && scope()->function() != NULL) { | 279 if (scope()->is_function_scope() && scope()->function() != NULL) { |
280 VariableDeclaration* function = scope()->function(); | 280 VariableDeclaration* function = scope()->function(); |
281 ASSERT(function->proxy()->var()->mode() == CONST || | 281 ASSERT(function->proxy()->var()->mode() == CONST || |
282 function->proxy()->var()->mode() == CONST_HARMONY); | 282 function->proxy()->var()->mode() == CONST_HARMONY); |
283 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); | 283 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); |
284 VisitVariableDeclaration(function); | 284 VisitVariableDeclaration(function); |
285 } | 285 } |
286 VisitDeclarations(scope()->declarations()); | 286 VisitDeclarations(scope()->declarations()); |
287 } | 287 } |
288 | 288 |
289 { Comment cmnt(masm_, "[ Stack check"); | 289 { Comment cmnt(masm_, "[ Stack check"); |
290 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS); | 290 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); |
291 Label ok; | 291 Label ok; |
292 __ LoadRoot(t0, Heap::kStackLimitRootIndex); | 292 __ LoadRoot(t0, Heap::kStackLimitRootIndex); |
293 __ Branch(&ok, hs, sp, Operand(t0)); | 293 __ Branch(&ok, hs, sp, Operand(t0)); |
294 StackCheckStub stub; | 294 StackCheckStub stub; |
295 __ CallStub(&stub); | 295 __ CallStub(&stub); |
296 __ bind(&ok); | 296 __ bind(&ok); |
297 } | 297 } |
298 | 298 |
299 { Comment cmnt(masm_, "[ Body"); | 299 { Comment cmnt(masm_, "[ Body"); |
300 ASSERT(loop_depth() == 0); | 300 ASSERT(loop_depth() == 0); |
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1159 __ jmp(&loop); | 1159 __ jmp(&loop); |
1160 | 1160 |
1161 // We got a fixed array in register v0. Iterate through that. | 1161 // We got a fixed array in register v0. Iterate through that. |
1162 Label non_proxy; | 1162 Label non_proxy; |
1163 __ bind(&fixed_array); | 1163 __ bind(&fixed_array); |
1164 | 1164 |
1165 Handle<JSGlobalPropertyCell> cell = | 1165 Handle<JSGlobalPropertyCell> cell = |
1166 isolate()->factory()->NewJSGlobalPropertyCell( | 1166 isolate()->factory()->NewJSGlobalPropertyCell( |
1167 Handle<Object>( | 1167 Handle<Object>( |
1168 Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker))); | 1168 Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker))); |
1169 RecordTypeFeedbackCell(stmt->PrepareId(), cell); | 1169 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); |
1170 __ LoadHeapObject(a1, cell); | 1170 __ LoadHeapObject(a1, cell); |
1171 __ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); | 1171 __ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); |
1172 __ sw(a2, FieldMemOperand(a1, JSGlobalPropertyCell::kValueOffset)); | 1172 __ sw(a2, FieldMemOperand(a1, JSGlobalPropertyCell::kValueOffset)); |
1173 | 1173 |
1174 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check | 1174 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check |
1175 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object | 1175 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object |
1176 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 1176 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
1177 __ GetObjectType(a2, a3, a3); | 1177 __ GetObjectType(a2, a3, a3); |
1178 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE)); | 1178 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE)); |
1179 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy | 1179 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1632 case ObjectLiteral::Property::COMPUTED: | 1632 case ObjectLiteral::Property::COMPUTED: |
1633 if (key->handle()->IsSymbol()) { | 1633 if (key->handle()->IsSymbol()) { |
1634 if (property->emit_store()) { | 1634 if (property->emit_store()) { |
1635 VisitForAccumulatorValue(value); | 1635 VisitForAccumulatorValue(value); |
1636 __ mov(a0, result_register()); | 1636 __ mov(a0, result_register()); |
1637 __ li(a2, Operand(key->handle())); | 1637 __ li(a2, Operand(key->handle())); |
1638 __ lw(a1, MemOperand(sp)); | 1638 __ lw(a1, MemOperand(sp)); |
1639 Handle<Code> ic = is_classic_mode() | 1639 Handle<Code> ic = is_classic_mode() |
1640 ? isolate()->builtins()->StoreIC_Initialize() | 1640 ? isolate()->builtins()->StoreIC_Initialize() |
1641 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 1641 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
1642 CallIC(ic, RelocInfo::CODE_TARGET, key->id()); | 1642 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); |
1643 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1643 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1644 } else { | 1644 } else { |
1645 VisitForEffect(value); | 1645 VisitForEffect(value); |
1646 } | 1646 } |
1647 break; | 1647 break; |
1648 } | 1648 } |
1649 // Fall through. | 1649 // Fall through. |
1650 case ObjectLiteral::Property::PROTOTYPE: | 1650 case ObjectLiteral::Property::PROTOTYPE: |
1651 // Duplicate receiver on stack. | 1651 // Duplicate receiver on stack. |
1652 __ lw(a0, MemOperand(sp)); | 1652 __ lw(a0, MemOperand(sp)); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1905 } | 1905 } |
1906 | 1906 |
1907 | 1907 |
1908 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1908 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1909 SetSourcePosition(prop->position()); | 1909 SetSourcePosition(prop->position()); |
1910 Literal* key = prop->key()->AsLiteral(); | 1910 Literal* key = prop->key()->AsLiteral(); |
1911 __ mov(a0, result_register()); | 1911 __ mov(a0, result_register()); |
1912 __ li(a2, Operand(key->handle())); | 1912 __ li(a2, Operand(key->handle())); |
1913 // Call load IC. It has arguments receiver and property name a0 and a2. | 1913 // Call load IC. It has arguments receiver and property name a0 and a2. |
1914 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1914 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1915 CallIC(ic, RelocInfo::CODE_TARGET, prop->id()); | 1915 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); |
1916 } | 1916 } |
1917 | 1917 |
1918 | 1918 |
1919 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1919 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1920 SetSourcePosition(prop->position()); | 1920 SetSourcePosition(prop->position()); |
1921 __ mov(a0, result_register()); | 1921 __ mov(a0, result_register()); |
1922 // Call keyed load IC. It has arguments key and receiver in a0 and a1. | 1922 // Call keyed load IC. It has arguments key and receiver in a0 and a1. |
1923 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1923 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
1924 CallIC(ic, RelocInfo::CODE_TARGET, prop->id()); | 1924 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); |
1925 } | 1925 } |
1926 | 1926 |
1927 | 1927 |
1928 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1928 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
1929 Token::Value op, | 1929 Token::Value op, |
1930 OverwriteMode mode, | 1930 OverwriteMode mode, |
1931 Expression* left_expr, | 1931 Expression* left_expr, |
1932 Expression* right_expr) { | 1932 Expression* right_expr) { |
1933 Label done, smi_case, stub_call; | 1933 Label done, smi_case, stub_call; |
1934 | 1934 |
1935 Register scratch1 = a2; | 1935 Register scratch1 = a2; |
1936 Register scratch2 = a3; | 1936 Register scratch2 = a3; |
1937 | 1937 |
1938 // Get the arguments. | 1938 // Get the arguments. |
1939 Register left = a1; | 1939 Register left = a1; |
1940 Register right = a0; | 1940 Register right = a0; |
1941 __ pop(left); | 1941 __ pop(left); |
1942 __ mov(a0, result_register()); | 1942 __ mov(a0, result_register()); |
1943 | 1943 |
1944 // Perform combined smi check on both operands. | 1944 // Perform combined smi check on both operands. |
1945 __ Or(scratch1, left, Operand(right)); | 1945 __ Or(scratch1, left, Operand(right)); |
1946 STATIC_ASSERT(kSmiTag == 0); | 1946 STATIC_ASSERT(kSmiTag == 0); |
1947 JumpPatchSite patch_site(masm_); | 1947 JumpPatchSite patch_site(masm_); |
1948 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 1948 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
1949 | 1949 |
1950 __ bind(&stub_call); | 1950 __ bind(&stub_call); |
1951 BinaryOpStub stub(op, mode); | 1951 BinaryOpStub stub(op, mode); |
1952 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1952 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, |
| 1953 expr->BinaryOperationFeedbackId()); |
1953 patch_site.EmitPatchInfo(); | 1954 patch_site.EmitPatchInfo(); |
1954 __ jmp(&done); | 1955 __ jmp(&done); |
1955 | 1956 |
1956 __ bind(&smi_case); | 1957 __ bind(&smi_case); |
1957 // Smi case. This code works the same way as the smi-smi case in the type | 1958 // Smi case. This code works the same way as the smi-smi case in the type |
1958 // recording binary operation stub, see | 1959 // recording binary operation stub, see |
1959 // BinaryOpStub::GenerateSmiSmiOperation for comments. | 1960 // BinaryOpStub::GenerateSmiSmiOperation for comments. |
1960 switch (op) { | 1961 switch (op) { |
1961 case Token::SAR: | 1962 case Token::SAR: |
1962 __ Branch(&stub_call); | 1963 __ Branch(&stub_call); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2025 } | 2026 } |
2026 | 2027 |
2027 | 2028 |
2028 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2029 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
2029 Token::Value op, | 2030 Token::Value op, |
2030 OverwriteMode mode) { | 2031 OverwriteMode mode) { |
2031 __ mov(a0, result_register()); | 2032 __ mov(a0, result_register()); |
2032 __ pop(a1); | 2033 __ pop(a1); |
2033 BinaryOpStub stub(op, mode); | 2034 BinaryOpStub stub(op, mode); |
2034 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2035 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2035 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 2036 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, |
| 2037 expr->BinaryOperationFeedbackId()); |
2036 patch_site.EmitPatchInfo(); | 2038 patch_site.EmitPatchInfo(); |
2037 context()->Plug(v0); | 2039 context()->Plug(v0); |
2038 } | 2040 } |
2039 | 2041 |
2040 | 2042 |
2041 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2043 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
2042 // Invalid left-hand sides are rewritten to have a 'throw | 2044 // Invalid left-hand sides are rewritten to have a 'throw |
2043 // ReferenceError' on the left-hand side. | 2045 // ReferenceError' on the left-hand side. |
2044 if (!expr->IsValidLeftHandSide()) { | 2046 if (!expr->IsValidLeftHandSide()) { |
2045 VisitForEffect(expr); | 2047 VisitForEffect(expr); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2216 // receiver into fast case. | 2218 // receiver into fast case. |
2217 if (expr->ends_initialization_block()) { | 2219 if (expr->ends_initialization_block()) { |
2218 __ lw(a1, MemOperand(sp)); | 2220 __ lw(a1, MemOperand(sp)); |
2219 } else { | 2221 } else { |
2220 __ pop(a1); | 2222 __ pop(a1); |
2221 } | 2223 } |
2222 | 2224 |
2223 Handle<Code> ic = is_classic_mode() | 2225 Handle<Code> ic = is_classic_mode() |
2224 ? isolate()->builtins()->StoreIC_Initialize() | 2226 ? isolate()->builtins()->StoreIC_Initialize() |
2225 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 2227 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
2226 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2228 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); |
2227 | 2229 |
2228 // If the assignment ends an initialization block, revert to fast case. | 2230 // If the assignment ends an initialization block, revert to fast case. |
2229 if (expr->ends_initialization_block()) { | 2231 if (expr->ends_initialization_block()) { |
2230 __ push(v0); // Result of assignment, saved even if not needed. | 2232 __ push(v0); // Result of assignment, saved even if not needed. |
2231 // Receiver is under the result value. | 2233 // Receiver is under the result value. |
2232 __ lw(t0, MemOperand(sp, kPointerSize)); | 2234 __ lw(t0, MemOperand(sp, kPointerSize)); |
2233 __ push(t0); | 2235 __ push(t0); |
2234 __ CallRuntime(Runtime::kToFastProperties, 1); | 2236 __ CallRuntime(Runtime::kToFastProperties, 1); |
2235 __ pop(v0); | 2237 __ pop(v0); |
2236 __ Drop(1); | 2238 __ Drop(1); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2268 // receiver into fast case. | 2270 // receiver into fast case. |
2269 if (expr->ends_initialization_block()) { | 2271 if (expr->ends_initialization_block()) { |
2270 __ lw(a2, MemOperand(sp)); | 2272 __ lw(a2, MemOperand(sp)); |
2271 } else { | 2273 } else { |
2272 __ pop(a2); | 2274 __ pop(a2); |
2273 } | 2275 } |
2274 | 2276 |
2275 Handle<Code> ic = is_classic_mode() | 2277 Handle<Code> ic = is_classic_mode() |
2276 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2278 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2277 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2279 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2278 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2280 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); |
2279 | 2281 |
2280 // If the assignment ends an initialization block, revert to fast case. | 2282 // If the assignment ends an initialization block, revert to fast case. |
2281 if (expr->ends_initialization_block()) { | 2283 if (expr->ends_initialization_block()) { |
2282 __ push(v0); // Result of assignment, saved even if not needed. | 2284 __ push(v0); // Result of assignment, saved even if not needed. |
2283 // Receiver is under the result value. | 2285 // Receiver is under the result value. |
2284 __ lw(t0, MemOperand(sp, kPointerSize)); | 2286 __ lw(t0, MemOperand(sp, kPointerSize)); |
2285 __ push(t0); | 2287 __ push(t0); |
2286 __ CallRuntime(Runtime::kToFastProperties, 1); | 2288 __ CallRuntime(Runtime::kToFastProperties, 1); |
2287 __ pop(v0); | 2289 __ pop(v0); |
2288 __ Drop(1); | 2290 __ Drop(1); |
(...skipping 17 matching lines...) Expand all Loading... |
2306 VisitForAccumulatorValue(expr->key()); | 2308 VisitForAccumulatorValue(expr->key()); |
2307 __ pop(a1); | 2309 __ pop(a1); |
2308 EmitKeyedPropertyLoad(expr); | 2310 EmitKeyedPropertyLoad(expr); |
2309 context()->Plug(v0); | 2311 context()->Plug(v0); |
2310 } | 2312 } |
2311 } | 2313 } |
2312 | 2314 |
2313 | 2315 |
2314 void FullCodeGenerator::CallIC(Handle<Code> code, | 2316 void FullCodeGenerator::CallIC(Handle<Code> code, |
2315 RelocInfo::Mode rmode, | 2317 RelocInfo::Mode rmode, |
2316 unsigned ast_id) { | 2318 TypeFeedbackId id) { |
2317 ic_total_count_++; | 2319 ic_total_count_++; |
2318 __ Call(code, rmode, ast_id); | 2320 __ Call(code, rmode, id); |
2319 } | 2321 } |
2320 | 2322 |
2321 | 2323 |
2322 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2324 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
2323 Handle<Object> name, | 2325 Handle<Object> name, |
2324 RelocInfo::Mode mode) { | 2326 RelocInfo::Mode mode) { |
2325 // Code common for calls using the IC. | 2327 // Code common for calls using the IC. |
2326 ZoneList<Expression*>* args = expr->arguments(); | 2328 ZoneList<Expression*>* args = expr->arguments(); |
2327 int arg_count = args->length(); | 2329 int arg_count = args->length(); |
2328 { PreservePositionScope scope(masm()->positions_recorder()); | 2330 { PreservePositionScope scope(masm()->positions_recorder()); |
2329 for (int i = 0; i < arg_count; i++) { | 2331 for (int i = 0; i < arg_count; i++) { |
2330 VisitForStackValue(args->at(i)); | 2332 VisitForStackValue(args->at(i)); |
2331 } | 2333 } |
2332 __ li(a2, Operand(name)); | 2334 __ li(a2, Operand(name)); |
2333 } | 2335 } |
2334 // Record source position for debugger. | 2336 // Record source position for debugger. |
2335 SetSourcePosition(expr->position()); | 2337 SetSourcePosition(expr->position()); |
2336 // Call the IC initialization code. | 2338 // Call the IC initialization code. |
2337 Handle<Code> ic = | 2339 Handle<Code> ic = |
2338 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2340 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
2339 CallIC(ic, mode, expr->id()); | 2341 CallIC(ic, mode, expr->CallFeedbackId()); |
2340 RecordJSReturnSite(expr); | 2342 RecordJSReturnSite(expr); |
2341 // Restore context register. | 2343 // Restore context register. |
2342 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2344 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2343 context()->Plug(v0); | 2345 context()->Plug(v0); |
2344 } | 2346 } |
2345 | 2347 |
2346 | 2348 |
2347 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2349 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2348 Expression* key) { | 2350 Expression* key) { |
2349 // Load the key. | 2351 // Load the key. |
(...skipping 12 matching lines...) Expand all Loading... |
2362 for (int i = 0; i < arg_count; i++) { | 2364 for (int i = 0; i < arg_count; i++) { |
2363 VisitForStackValue(args->at(i)); | 2365 VisitForStackValue(args->at(i)); |
2364 } | 2366 } |
2365 } | 2367 } |
2366 // Record source position for debugger. | 2368 // Record source position for debugger. |
2367 SetSourcePosition(expr->position()); | 2369 SetSourcePosition(expr->position()); |
2368 // Call the IC initialization code. | 2370 // Call the IC initialization code. |
2369 Handle<Code> ic = | 2371 Handle<Code> ic = |
2370 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2372 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
2371 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2373 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
2372 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2374 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); |
2373 RecordJSReturnSite(expr); | 2375 RecordJSReturnSite(expr); |
2374 // Restore context register. | 2376 // Restore context register. |
2375 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2377 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2376 context()->DropAndPlug(1, v0); // Drop the key still on the stack. | 2378 context()->DropAndPlug(1, v0); // Drop the key still on the stack. |
2377 } | 2379 } |
2378 | 2380 |
2379 | 2381 |
2380 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2382 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
2381 // Code common for calls using the call stub. | 2383 // Code common for calls using the call stub. |
2382 ZoneList<Expression*>* args = expr->arguments(); | 2384 ZoneList<Expression*>* args = expr->arguments(); |
2383 int arg_count = args->length(); | 2385 int arg_count = args->length(); |
2384 { PreservePositionScope scope(masm()->positions_recorder()); | 2386 { PreservePositionScope scope(masm()->positions_recorder()); |
2385 for (int i = 0; i < arg_count; i++) { | 2387 for (int i = 0; i < arg_count; i++) { |
2386 VisitForStackValue(args->at(i)); | 2388 VisitForStackValue(args->at(i)); |
2387 } | 2389 } |
2388 } | 2390 } |
2389 // Record source position for debugger. | 2391 // Record source position for debugger. |
2390 SetSourcePosition(expr->position()); | 2392 SetSourcePosition(expr->position()); |
2391 | 2393 |
2392 // Record call targets. | 2394 // Record call targets. |
2393 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); | 2395 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); |
2394 Handle<Object> uninitialized = | 2396 Handle<Object> uninitialized = |
2395 TypeFeedbackCells::UninitializedSentinel(isolate()); | 2397 TypeFeedbackCells::UninitializedSentinel(isolate()); |
2396 Handle<JSGlobalPropertyCell> cell = | 2398 Handle<JSGlobalPropertyCell> cell = |
2397 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | 2399 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); |
2398 RecordTypeFeedbackCell(expr->id(), cell); | 2400 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); |
2399 __ li(a2, Operand(cell)); | 2401 __ li(a2, Operand(cell)); |
2400 | 2402 |
2401 CallFunctionStub stub(arg_count, flags); | 2403 CallFunctionStub stub(arg_count, flags); |
2402 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2404 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2403 __ CallStub(&stub); | 2405 __ CallStub(&stub); |
2404 RecordJSReturnSite(expr); | 2406 RecordJSReturnSite(expr); |
2405 // Restore context register. | 2407 // Restore context register. |
2406 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2408 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2407 context()->DropAndPlug(1, v0); | 2409 context()->DropAndPlug(1, v0); |
2408 } | 2410 } |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2583 | 2585 |
2584 // Load function and argument count into a1 and a0. | 2586 // Load function and argument count into a1 and a0. |
2585 __ li(a0, Operand(arg_count)); | 2587 __ li(a0, Operand(arg_count)); |
2586 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); | 2588 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); |
2587 | 2589 |
2588 // Record call targets in unoptimized code. | 2590 // Record call targets in unoptimized code. |
2589 Handle<Object> uninitialized = | 2591 Handle<Object> uninitialized = |
2590 TypeFeedbackCells::UninitializedSentinel(isolate()); | 2592 TypeFeedbackCells::UninitializedSentinel(isolate()); |
2591 Handle<JSGlobalPropertyCell> cell = | 2593 Handle<JSGlobalPropertyCell> cell = |
2592 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | 2594 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); |
2593 RecordTypeFeedbackCell(expr->id(), cell); | 2595 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); |
2594 __ li(a2, Operand(cell)); | 2596 __ li(a2, Operand(cell)); |
2595 | 2597 |
2596 CallConstructStub stub(RECORD_CALL_TARGET); | 2598 CallConstructStub stub(RECORD_CALL_TARGET); |
2597 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 2599 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
2598 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2600 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2599 context()->Plug(v0); | 2601 context()->Plug(v0); |
2600 } | 2602 } |
2601 | 2603 |
2602 | 2604 |
2603 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2605 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
(...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3881 for (int i = 0; i < arg_count; i++) { | 3883 for (int i = 0; i < arg_count; i++) { |
3882 VisitForStackValue(args->at(i)); | 3884 VisitForStackValue(args->at(i)); |
3883 } | 3885 } |
3884 | 3886 |
3885 if (expr->is_jsruntime()) { | 3887 if (expr->is_jsruntime()) { |
3886 // Call the JS runtime function. | 3888 // Call the JS runtime function. |
3887 __ li(a2, Operand(expr->name())); | 3889 __ li(a2, Operand(expr->name())); |
3888 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 3890 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
3889 Handle<Code> ic = | 3891 Handle<Code> ic = |
3890 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 3892 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
3891 CallIC(ic, mode, expr->id()); | 3893 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
3892 // Restore context register. | 3894 // Restore context register. |
3893 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3895 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3894 } else { | 3896 } else { |
3895 // Call the C runtime function. | 3897 // Call the C runtime function. |
3896 __ CallRuntime(expr->function(), arg_count); | 3898 __ CallRuntime(expr->function(), arg_count); |
3897 } | 3899 } |
3898 context()->Plug(v0); | 3900 context()->Plug(v0); |
3899 } | 3901 } |
3900 | 3902 |
3901 | 3903 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4037 // TODO(svenpanne): Allowing format strings in Comment would be nice here... | 4039 // TODO(svenpanne): Allowing format strings in Comment would be nice here... |
4038 Comment cmt(masm_, comment); | 4040 Comment cmt(masm_, comment); |
4039 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 4041 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
4040 UnaryOverwriteMode overwrite = | 4042 UnaryOverwriteMode overwrite = |
4041 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 4043 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
4042 UnaryOpStub stub(expr->op(), overwrite); | 4044 UnaryOpStub stub(expr->op(), overwrite); |
4043 // GenericUnaryOpStub expects the argument to be in a0. | 4045 // GenericUnaryOpStub expects the argument to be in a0. |
4044 VisitForAccumulatorValue(expr->expression()); | 4046 VisitForAccumulatorValue(expr->expression()); |
4045 SetSourcePosition(expr->position()); | 4047 SetSourcePosition(expr->position()); |
4046 __ mov(a0, result_register()); | 4048 __ mov(a0, result_register()); |
4047 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 4049 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, |
| 4050 expr->UnaryOperationFeedbackId()); |
4048 context()->Plug(v0); | 4051 context()->Plug(v0); |
4049 } | 4052 } |
4050 | 4053 |
4051 | 4054 |
4052 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4055 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4053 Comment cmnt(masm_, "[ CountOperation"); | 4056 Comment cmnt(masm_, "[ CountOperation"); |
4054 SetSourcePosition(expr->position()); | 4057 SetSourcePosition(expr->position()); |
4055 | 4058 |
4056 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' | 4059 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' |
4057 // as the left-hand side. | 4060 // as the left-hand side. |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4148 // We could eliminate this smi check if we split the code at | 4151 // We could eliminate this smi check if we split the code at |
4149 // the first smi check before calling ToNumber. | 4152 // the first smi check before calling ToNumber. |
4150 patch_site.EmitJumpIfSmi(v0, &done); | 4153 patch_site.EmitJumpIfSmi(v0, &done); |
4151 __ bind(&stub_call); | 4154 __ bind(&stub_call); |
4152 } | 4155 } |
4153 | 4156 |
4154 // Record position before stub call. | 4157 // Record position before stub call. |
4155 SetSourcePosition(expr->position()); | 4158 SetSourcePosition(expr->position()); |
4156 | 4159 |
4157 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); | 4160 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); |
4158 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); | 4161 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountBinOpFeedbackId()); |
4159 patch_site.EmitPatchInfo(); | 4162 patch_site.EmitPatchInfo(); |
4160 __ bind(&done); | 4163 __ bind(&done); |
4161 | 4164 |
4162 // Store the value returned in v0. | 4165 // Store the value returned in v0. |
4163 switch (assign_type) { | 4166 switch (assign_type) { |
4164 case VARIABLE: | 4167 case VARIABLE: |
4165 if (expr->is_postfix()) { | 4168 if (expr->is_postfix()) { |
4166 { EffectContext context(this); | 4169 { EffectContext context(this); |
4167 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4170 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
4168 Token::ASSIGN); | 4171 Token::ASSIGN); |
(...skipping 12 matching lines...) Expand all Loading... |
4181 context()->Plug(v0); | 4184 context()->Plug(v0); |
4182 } | 4185 } |
4183 break; | 4186 break; |
4184 case NAMED_PROPERTY: { | 4187 case NAMED_PROPERTY: { |
4185 __ mov(a0, result_register()); // Value. | 4188 __ mov(a0, result_register()); // Value. |
4186 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); // Name. | 4189 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); // Name. |
4187 __ pop(a1); // Receiver. | 4190 __ pop(a1); // Receiver. |
4188 Handle<Code> ic = is_classic_mode() | 4191 Handle<Code> ic = is_classic_mode() |
4189 ? isolate()->builtins()->StoreIC_Initialize() | 4192 ? isolate()->builtins()->StoreIC_Initialize() |
4190 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 4193 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
4191 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4194 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); |
4192 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4195 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4193 if (expr->is_postfix()) { | 4196 if (expr->is_postfix()) { |
4194 if (!context()->IsEffect()) { | 4197 if (!context()->IsEffect()) { |
4195 context()->PlugTOS(); | 4198 context()->PlugTOS(); |
4196 } | 4199 } |
4197 } else { | 4200 } else { |
4198 context()->Plug(v0); | 4201 context()->Plug(v0); |
4199 } | 4202 } |
4200 break; | 4203 break; |
4201 } | 4204 } |
4202 case KEYED_PROPERTY: { | 4205 case KEYED_PROPERTY: { |
4203 __ mov(a0, result_register()); // Value. | 4206 __ mov(a0, result_register()); // Value. |
4204 __ pop(a1); // Key. | 4207 __ pop(a1); // Key. |
4205 __ pop(a2); // Receiver. | 4208 __ pop(a2); // Receiver. |
4206 Handle<Code> ic = is_classic_mode() | 4209 Handle<Code> ic = is_classic_mode() |
4207 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4210 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
4208 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4211 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
4209 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4212 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); |
4210 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4213 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4211 if (expr->is_postfix()) { | 4214 if (expr->is_postfix()) { |
4212 if (!context()->IsEffect()) { | 4215 if (!context()->IsEffect()) { |
4213 context()->PlugTOS(); | 4216 context()->PlugTOS(); |
4214 } | 4217 } |
4215 } else { | 4218 } else { |
4216 context()->Plug(v0); | 4219 context()->Plug(v0); |
4217 } | 4220 } |
4218 break; | 4221 break; |
4219 } | 4222 } |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4403 if (inline_smi_code) { | 4406 if (inline_smi_code) { |
4404 Label slow_case; | 4407 Label slow_case; |
4405 __ Or(a2, a0, Operand(a1)); | 4408 __ Or(a2, a0, Operand(a1)); |
4406 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 4409 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
4407 Split(cc, a1, Operand(a0), if_true, if_false, NULL); | 4410 Split(cc, a1, Operand(a0), if_true, if_false, NULL); |
4408 __ bind(&slow_case); | 4411 __ bind(&slow_case); |
4409 } | 4412 } |
4410 // Record position and call the compare IC. | 4413 // Record position and call the compare IC. |
4411 SetSourcePosition(expr->position()); | 4414 SetSourcePosition(expr->position()); |
4412 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4415 Handle<Code> ic = CompareIC::GetUninitialized(op); |
4413 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4416 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); |
4414 patch_site.EmitPatchInfo(); | 4417 patch_site.EmitPatchInfo(); |
4415 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4418 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4416 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4419 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); |
4417 } | 4420 } |
4418 } | 4421 } |
4419 | 4422 |
4420 // Convert the result of the comparison into one expected for this | 4423 // Convert the result of the comparison into one expected for this |
4421 // expression's context. | 4424 // expression's context. |
4422 context()->Plug(if_true, if_false); | 4425 context()->Plug(if_true, if_false); |
4423 } | 4426 } |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4607 *context_length = 0; | 4610 *context_length = 0; |
4608 return previous_; | 4611 return previous_; |
4609 } | 4612 } |
4610 | 4613 |
4611 | 4614 |
4612 #undef __ | 4615 #undef __ |
4613 | 4616 |
4614 } } // namespace v8::internal | 4617 } } // namespace v8::internal |
4615 | 4618 |
4616 #endif // V8_TARGET_ARCH_MIPS | 4619 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |