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