| 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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 __ CallRuntime(Runtime::kTraceEnter, 0); | 257 __ CallRuntime(Runtime::kTraceEnter, 0); |
| 258 } | 258 } |
| 259 | 259 |
| 260 // Visit the declarations and body unless there is an illegal | 260 // Visit the declarations and body unless there is an illegal |
| 261 // redeclaration. | 261 // redeclaration. |
| 262 if (scope()->HasIllegalRedeclaration()) { | 262 if (scope()->HasIllegalRedeclaration()) { |
| 263 Comment cmnt(masm_, "[ Declarations"); | 263 Comment cmnt(masm_, "[ Declarations"); |
| 264 scope()->VisitIllegalRedeclaration(this); | 264 scope()->VisitIllegalRedeclaration(this); |
| 265 | 265 |
| 266 } else { | 266 } else { |
| 267 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS); | 267 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); |
| 268 { Comment cmnt(masm_, "[ Declarations"); | 268 { Comment cmnt(masm_, "[ Declarations"); |
| 269 // For named function expressions, declare the function name as a | 269 // For named function expressions, declare the function name as a |
| 270 // constant. | 270 // constant. |
| 271 if (scope()->is_function_scope() && scope()->function() != NULL) { | 271 if (scope()->is_function_scope() && scope()->function() != NULL) { |
| 272 VariableDeclaration* function = scope()->function(); | 272 VariableDeclaration* function = scope()->function(); |
| 273 ASSERT(function->proxy()->var()->mode() == CONST || | 273 ASSERT(function->proxy()->var()->mode() == CONST || |
| 274 function->proxy()->var()->mode() == CONST_HARMONY); | 274 function->proxy()->var()->mode() == CONST_HARMONY); |
| 275 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); | 275 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); |
| 276 VisitVariableDeclaration(function); | 276 VisitVariableDeclaration(function); |
| 277 } | 277 } |
| 278 VisitDeclarations(scope()->declarations()); | 278 VisitDeclarations(scope()->declarations()); |
| 279 } | 279 } |
| 280 | 280 |
| 281 { Comment cmnt(masm_, "[ Stack check"); | 281 { Comment cmnt(masm_, "[ Stack check"); |
| 282 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS); | 282 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); |
| 283 Label ok; | 283 Label ok; |
| 284 __ LoadRoot(ip, Heap::kStackLimitRootIndex); | 284 __ LoadRoot(ip, Heap::kStackLimitRootIndex); |
| 285 __ cmp(sp, Operand(ip)); | 285 __ cmp(sp, Operand(ip)); |
| 286 __ b(hs, &ok); | 286 __ b(hs, &ok); |
| 287 StackCheckStub stub; | 287 StackCheckStub stub; |
| 288 __ CallStub(&stub); | 288 __ CallStub(&stub); |
| 289 __ bind(&ok); | 289 __ bind(&ok); |
| 290 } | 290 } |
| 291 | 291 |
| 292 { Comment cmnt(masm_, "[ Body"); | 292 { Comment cmnt(masm_, "[ Body"); |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 __ jmp(&loop); | 1152 __ jmp(&loop); |
| 1153 | 1153 |
| 1154 // We got a fixed array in register r0. Iterate through that. | 1154 // We got a fixed array in register r0. Iterate through that. |
| 1155 Label non_proxy; | 1155 Label non_proxy; |
| 1156 __ bind(&fixed_array); | 1156 __ bind(&fixed_array); |
| 1157 | 1157 |
| 1158 Handle<JSGlobalPropertyCell> cell = | 1158 Handle<JSGlobalPropertyCell> cell = |
| 1159 isolate()->factory()->NewJSGlobalPropertyCell( | 1159 isolate()->factory()->NewJSGlobalPropertyCell( |
| 1160 Handle<Object>( | 1160 Handle<Object>( |
| 1161 Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker))); | 1161 Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker))); |
| 1162 RecordTypeFeedbackCell(stmt->PrepareId(), cell); | 1162 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); |
| 1163 __ LoadHeapObject(r1, cell); | 1163 __ LoadHeapObject(r1, cell); |
| 1164 __ mov(r2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); | 1164 __ mov(r2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); |
| 1165 __ str(r2, FieldMemOperand(r1, JSGlobalPropertyCell::kValueOffset)); | 1165 __ str(r2, FieldMemOperand(r1, JSGlobalPropertyCell::kValueOffset)); |
| 1166 | 1166 |
| 1167 __ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check | 1167 __ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check |
| 1168 __ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object | 1168 __ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object |
| 1169 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 1169 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| 1170 __ CompareObjectType(r2, r3, r3, LAST_JS_PROXY_TYPE); | 1170 __ CompareObjectType(r2, r3, r3, LAST_JS_PROXY_TYPE); |
| 1171 __ b(gt, &non_proxy); | 1171 __ b(gt, &non_proxy); |
| 1172 __ mov(r1, Operand(Smi::FromInt(0))); // Zero indicates proxy | 1172 __ mov(r1, Operand(Smi::FromInt(0))); // Zero indicates proxy |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1624 // Fall through. | 1624 // Fall through. |
| 1625 case ObjectLiteral::Property::COMPUTED: | 1625 case ObjectLiteral::Property::COMPUTED: |
| 1626 if (key->handle()->IsSymbol()) { | 1626 if (key->handle()->IsSymbol()) { |
| 1627 if (property->emit_store()) { | 1627 if (property->emit_store()) { |
| 1628 VisitForAccumulatorValue(value); | 1628 VisitForAccumulatorValue(value); |
| 1629 __ mov(r2, Operand(key->handle())); | 1629 __ mov(r2, Operand(key->handle())); |
| 1630 __ ldr(r1, MemOperand(sp)); | 1630 __ ldr(r1, MemOperand(sp)); |
| 1631 Handle<Code> ic = is_classic_mode() | 1631 Handle<Code> ic = is_classic_mode() |
| 1632 ? isolate()->builtins()->StoreIC_Initialize() | 1632 ? isolate()->builtins()->StoreIC_Initialize() |
| 1633 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 1633 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
| 1634 CallIC(ic, RelocInfo::CODE_TARGET, key->id()); | 1634 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); |
| 1635 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1635 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1636 } else { | 1636 } else { |
| 1637 VisitForEffect(value); | 1637 VisitForEffect(value); |
| 1638 } | 1638 } |
| 1639 break; | 1639 break; |
| 1640 } | 1640 } |
| 1641 // Fall through. | 1641 // Fall through. |
| 1642 case ObjectLiteral::Property::PROTOTYPE: | 1642 case ObjectLiteral::Property::PROTOTYPE: |
| 1643 // Duplicate receiver on stack. | 1643 // Duplicate receiver on stack. |
| 1644 __ ldr(r0, MemOperand(sp)); | 1644 __ ldr(r0, MemOperand(sp)); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1891 } | 1891 } |
| 1892 } | 1892 } |
| 1893 | 1893 |
| 1894 | 1894 |
| 1895 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1895 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1896 SetSourcePosition(prop->position()); | 1896 SetSourcePosition(prop->position()); |
| 1897 Literal* key = prop->key()->AsLiteral(); | 1897 Literal* key = prop->key()->AsLiteral(); |
| 1898 __ mov(r2, Operand(key->handle())); | 1898 __ mov(r2, Operand(key->handle())); |
| 1899 // Call load IC. It has arguments receiver and property name r0 and r2. | 1899 // Call load IC. It has arguments receiver and property name r0 and r2. |
| 1900 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1900 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1901 CallIC(ic, RelocInfo::CODE_TARGET, prop->id()); | 1901 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); |
| 1902 } | 1902 } |
| 1903 | 1903 |
| 1904 | 1904 |
| 1905 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1905 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1906 SetSourcePosition(prop->position()); | 1906 SetSourcePosition(prop->position()); |
| 1907 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1907 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1908 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1908 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1909 CallIC(ic, RelocInfo::CODE_TARGET, prop->id()); | 1909 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); |
| 1910 } | 1910 } |
| 1911 | 1911 |
| 1912 | 1912 |
| 1913 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1913 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 1914 Token::Value op, | 1914 Token::Value op, |
| 1915 OverwriteMode mode, | 1915 OverwriteMode mode, |
| 1916 Expression* left_expr, | 1916 Expression* left_expr, |
| 1917 Expression* right_expr) { | 1917 Expression* right_expr) { |
| 1918 Label done, smi_case, stub_call; | 1918 Label done, smi_case, stub_call; |
| 1919 | 1919 |
| 1920 Register scratch1 = r2; | 1920 Register scratch1 = r2; |
| 1921 Register scratch2 = r3; | 1921 Register scratch2 = r3; |
| 1922 | 1922 |
| 1923 // Get the arguments. | 1923 // Get the arguments. |
| 1924 Register left = r1; | 1924 Register left = r1; |
| 1925 Register right = r0; | 1925 Register right = r0; |
| 1926 __ pop(left); | 1926 __ pop(left); |
| 1927 | 1927 |
| 1928 // Perform combined smi check on both operands. | 1928 // Perform combined smi check on both operands. |
| 1929 __ orr(scratch1, left, Operand(right)); | 1929 __ orr(scratch1, left, Operand(right)); |
| 1930 STATIC_ASSERT(kSmiTag == 0); | 1930 STATIC_ASSERT(kSmiTag == 0); |
| 1931 JumpPatchSite patch_site(masm_); | 1931 JumpPatchSite patch_site(masm_); |
| 1932 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 1932 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
| 1933 | 1933 |
| 1934 __ bind(&stub_call); | 1934 __ bind(&stub_call); |
| 1935 BinaryOpStub stub(op, mode); | 1935 BinaryOpStub stub(op, mode); |
| 1936 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1936 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, |
| 1937 expr->BinaryOperationFeedbackId()); |
| 1937 patch_site.EmitPatchInfo(); | 1938 patch_site.EmitPatchInfo(); |
| 1938 __ jmp(&done); | 1939 __ jmp(&done); |
| 1939 | 1940 |
| 1940 __ bind(&smi_case); | 1941 __ bind(&smi_case); |
| 1941 // Smi case. This code works the same way as the smi-smi case in the type | 1942 // Smi case. This code works the same way as the smi-smi case in the type |
| 1942 // recording binary operation stub, see | 1943 // recording binary operation stub, see |
| 1943 // BinaryOpStub::GenerateSmiSmiOperation for comments. | 1944 // BinaryOpStub::GenerateSmiSmiOperation for comments. |
| 1944 switch (op) { | 1945 switch (op) { |
| 1945 case Token::SAR: | 1946 case Token::SAR: |
| 1946 __ b(&stub_call); | 1947 __ b(&stub_call); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2009 context()->Plug(r0); | 2010 context()->Plug(r0); |
| 2010 } | 2011 } |
| 2011 | 2012 |
| 2012 | 2013 |
| 2013 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2014 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 2014 Token::Value op, | 2015 Token::Value op, |
| 2015 OverwriteMode mode) { | 2016 OverwriteMode mode) { |
| 2016 __ pop(r1); | 2017 __ pop(r1); |
| 2017 BinaryOpStub stub(op, mode); | 2018 BinaryOpStub stub(op, mode); |
| 2018 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2019 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2019 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 2020 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, |
| 2021 expr->BinaryOperationFeedbackId()); |
| 2020 patch_site.EmitPatchInfo(); | 2022 patch_site.EmitPatchInfo(); |
| 2021 context()->Plug(r0); | 2023 context()->Plug(r0); |
| 2022 } | 2024 } |
| 2023 | 2025 |
| 2024 | 2026 |
| 2025 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2027 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
| 2026 // Invalid left-hand sides are rewritten to have a 'throw | 2028 // Invalid left-hand sides are rewritten to have a 'throw |
| 2027 // ReferenceError' on the left-hand side. | 2029 // ReferenceError' on the left-hand side. |
| 2028 if (!expr->IsValidLeftHandSide()) { | 2030 if (!expr->IsValidLeftHandSide()) { |
| 2029 VisitForEffect(expr); | 2031 VisitForEffect(expr); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2198 // receiver into fast case. | 2200 // receiver into fast case. |
| 2199 if (expr->ends_initialization_block()) { | 2201 if (expr->ends_initialization_block()) { |
| 2200 __ ldr(r1, MemOperand(sp)); | 2202 __ ldr(r1, MemOperand(sp)); |
| 2201 } else { | 2203 } else { |
| 2202 __ pop(r1); | 2204 __ pop(r1); |
| 2203 } | 2205 } |
| 2204 | 2206 |
| 2205 Handle<Code> ic = is_classic_mode() | 2207 Handle<Code> ic = is_classic_mode() |
| 2206 ? isolate()->builtins()->StoreIC_Initialize() | 2208 ? isolate()->builtins()->StoreIC_Initialize() |
| 2207 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 2209 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
| 2208 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2210 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); |
| 2209 | 2211 |
| 2210 // If the assignment ends an initialization block, revert to fast case. | 2212 // If the assignment ends an initialization block, revert to fast case. |
| 2211 if (expr->ends_initialization_block()) { | 2213 if (expr->ends_initialization_block()) { |
| 2212 __ push(r0); // Result of assignment, saved even if not needed. | 2214 __ push(r0); // Result of assignment, saved even if not needed. |
| 2213 // Receiver is under the result value. | 2215 // Receiver is under the result value. |
| 2214 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2216 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 2215 __ push(ip); | 2217 __ push(ip); |
| 2216 __ CallRuntime(Runtime::kToFastProperties, 1); | 2218 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2217 __ pop(r0); | 2219 __ pop(r0); |
| 2218 __ Drop(1); | 2220 __ Drop(1); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2244 // receiver into fast case. | 2246 // receiver into fast case. |
| 2245 if (expr->ends_initialization_block()) { | 2247 if (expr->ends_initialization_block()) { |
| 2246 __ ldr(r2, MemOperand(sp)); | 2248 __ ldr(r2, MemOperand(sp)); |
| 2247 } else { | 2249 } else { |
| 2248 __ pop(r2); | 2250 __ pop(r2); |
| 2249 } | 2251 } |
| 2250 | 2252 |
| 2251 Handle<Code> ic = is_classic_mode() | 2253 Handle<Code> ic = is_classic_mode() |
| 2252 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2254 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2253 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2255 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2254 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2256 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); |
| 2255 | 2257 |
| 2256 // If the assignment ends an initialization block, revert to fast case. | 2258 // If the assignment ends an initialization block, revert to fast case. |
| 2257 if (expr->ends_initialization_block()) { | 2259 if (expr->ends_initialization_block()) { |
| 2258 __ push(r0); // Result of assignment, saved even if not needed. | 2260 __ push(r0); // Result of assignment, saved even if not needed. |
| 2259 // Receiver is under the result value. | 2261 // Receiver is under the result value. |
| 2260 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2262 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 2261 __ push(ip); | 2263 __ push(ip); |
| 2262 __ CallRuntime(Runtime::kToFastProperties, 1); | 2264 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2263 __ pop(r0); | 2265 __ pop(r0); |
| 2264 __ Drop(1); | 2266 __ Drop(1); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2282 VisitForAccumulatorValue(expr->key()); | 2284 VisitForAccumulatorValue(expr->key()); |
| 2283 __ pop(r1); | 2285 __ pop(r1); |
| 2284 EmitKeyedPropertyLoad(expr); | 2286 EmitKeyedPropertyLoad(expr); |
| 2285 context()->Plug(r0); | 2287 context()->Plug(r0); |
| 2286 } | 2288 } |
| 2287 } | 2289 } |
| 2288 | 2290 |
| 2289 | 2291 |
| 2290 void FullCodeGenerator::CallIC(Handle<Code> code, | 2292 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2291 RelocInfo::Mode rmode, | 2293 RelocInfo::Mode rmode, |
| 2292 unsigned ast_id) { | 2294 TypeFeedbackId ast_id) { |
| 2293 ic_total_count_++; | 2295 ic_total_count_++; |
| 2294 __ Call(code, rmode, ast_id); | 2296 __ Call(code, rmode, ast_id); |
| 2295 } | 2297 } |
| 2296 | 2298 |
| 2297 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2299 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
| 2298 Handle<Object> name, | 2300 Handle<Object> name, |
| 2299 RelocInfo::Mode mode) { | 2301 RelocInfo::Mode mode) { |
| 2300 // Code common for calls using the IC. | 2302 // Code common for calls using the IC. |
| 2301 ZoneList<Expression*>* args = expr->arguments(); | 2303 ZoneList<Expression*>* args = expr->arguments(); |
| 2302 int arg_count = args->length(); | 2304 int arg_count = args->length(); |
| 2303 { PreservePositionScope scope(masm()->positions_recorder()); | 2305 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2304 for (int i = 0; i < arg_count; i++) { | 2306 for (int i = 0; i < arg_count; i++) { |
| 2305 VisitForStackValue(args->at(i)); | 2307 VisitForStackValue(args->at(i)); |
| 2306 } | 2308 } |
| 2307 __ mov(r2, Operand(name)); | 2309 __ mov(r2, Operand(name)); |
| 2308 } | 2310 } |
| 2309 // Record source position for debugger. | 2311 // Record source position for debugger. |
| 2310 SetSourcePosition(expr->position()); | 2312 SetSourcePosition(expr->position()); |
| 2311 // Call the IC initialization code. | 2313 // Call the IC initialization code. |
| 2312 Handle<Code> ic = | 2314 Handle<Code> ic = |
| 2313 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2315 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 2314 CallIC(ic, mode, expr->id()); | 2316 CallIC(ic, mode, expr->CallFeedbackId()); |
| 2315 RecordJSReturnSite(expr); | 2317 RecordJSReturnSite(expr); |
| 2316 // Restore context register. | 2318 // Restore context register. |
| 2317 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2319 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2318 context()->Plug(r0); | 2320 context()->Plug(r0); |
| 2319 } | 2321 } |
| 2320 | 2322 |
| 2321 | 2323 |
| 2322 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2324 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2323 Expression* key) { | 2325 Expression* key) { |
| 2324 // Load the key. | 2326 // Load the key. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2337 for (int i = 0; i < arg_count; i++) { | 2339 for (int i = 0; i < arg_count; i++) { |
| 2338 VisitForStackValue(args->at(i)); | 2340 VisitForStackValue(args->at(i)); |
| 2339 } | 2341 } |
| 2340 } | 2342 } |
| 2341 // Record source position for debugger. | 2343 // Record source position for debugger. |
| 2342 SetSourcePosition(expr->position()); | 2344 SetSourcePosition(expr->position()); |
| 2343 // Call the IC initialization code. | 2345 // Call the IC initialization code. |
| 2344 Handle<Code> ic = | 2346 Handle<Code> ic = |
| 2345 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2347 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
| 2346 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2348 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
| 2347 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 2349 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); |
| 2348 RecordJSReturnSite(expr); | 2350 RecordJSReturnSite(expr); |
| 2349 // Restore context register. | 2351 // Restore context register. |
| 2350 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2352 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2351 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 2353 context()->DropAndPlug(1, r0); // Drop the key still on the stack. |
| 2352 } | 2354 } |
| 2353 | 2355 |
| 2354 | 2356 |
| 2355 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2357 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| 2356 // Code common for calls using the call stub. | 2358 // Code common for calls using the call stub. |
| 2357 ZoneList<Expression*>* args = expr->arguments(); | 2359 ZoneList<Expression*>* args = expr->arguments(); |
| 2358 int arg_count = args->length(); | 2360 int arg_count = args->length(); |
| 2359 { PreservePositionScope scope(masm()->positions_recorder()); | 2361 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2360 for (int i = 0; i < arg_count; i++) { | 2362 for (int i = 0; i < arg_count; i++) { |
| 2361 VisitForStackValue(args->at(i)); | 2363 VisitForStackValue(args->at(i)); |
| 2362 } | 2364 } |
| 2363 } | 2365 } |
| 2364 // Record source position for debugger. | 2366 // Record source position for debugger. |
| 2365 SetSourcePosition(expr->position()); | 2367 SetSourcePosition(expr->position()); |
| 2366 | 2368 |
| 2367 // Record call targets in unoptimized code. | 2369 // Record call targets in unoptimized code. |
| 2368 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); | 2370 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); |
| 2369 Handle<Object> uninitialized = | 2371 Handle<Object> uninitialized = |
| 2370 TypeFeedbackCells::UninitializedSentinel(isolate()); | 2372 TypeFeedbackCells::UninitializedSentinel(isolate()); |
| 2371 Handle<JSGlobalPropertyCell> cell = | 2373 Handle<JSGlobalPropertyCell> cell = |
| 2372 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | 2374 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); |
| 2373 RecordTypeFeedbackCell(expr->id(), cell); | 2375 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); |
| 2374 __ mov(r2, Operand(cell)); | 2376 __ mov(r2, Operand(cell)); |
| 2375 | 2377 |
| 2376 CallFunctionStub stub(arg_count, flags); | 2378 CallFunctionStub stub(arg_count, flags); |
| 2377 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2379 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2378 __ CallStub(&stub); | 2380 __ CallStub(&stub); |
| 2379 RecordJSReturnSite(expr); | 2381 RecordJSReturnSite(expr); |
| 2380 // Restore context register. | 2382 // Restore context register. |
| 2381 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2383 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2382 context()->DropAndPlug(1, r0); | 2384 context()->DropAndPlug(1, r0); |
| 2383 } | 2385 } |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2559 | 2561 |
| 2560 // Load function and argument count into r1 and r0. | 2562 // Load function and argument count into r1 and r0. |
| 2561 __ mov(r0, Operand(arg_count)); | 2563 __ mov(r0, Operand(arg_count)); |
| 2562 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | 2564 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 2563 | 2565 |
| 2564 // Record call targets in unoptimized code. | 2566 // Record call targets in unoptimized code. |
| 2565 Handle<Object> uninitialized = | 2567 Handle<Object> uninitialized = |
| 2566 TypeFeedbackCells::UninitializedSentinel(isolate()); | 2568 TypeFeedbackCells::UninitializedSentinel(isolate()); |
| 2567 Handle<JSGlobalPropertyCell> cell = | 2569 Handle<JSGlobalPropertyCell> cell = |
| 2568 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | 2570 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); |
| 2569 RecordTypeFeedbackCell(expr->id(), cell); | 2571 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); |
| 2570 __ mov(r2, Operand(cell)); | 2572 __ mov(r2, Operand(cell)); |
| 2571 | 2573 |
| 2572 CallConstructStub stub(RECORD_CALL_TARGET); | 2574 CallConstructStub stub(RECORD_CALL_TARGET); |
| 2573 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 2575 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 2574 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2576 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
| 2575 context()->Plug(r0); | 2577 context()->Plug(r0); |
| 2576 } | 2578 } |
| 2577 | 2579 |
| 2578 | 2580 |
| 2579 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2581 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| (...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3840 for (int i = 0; i < arg_count; i++) { | 3842 for (int i = 0; i < arg_count; i++) { |
| 3841 VisitForStackValue(args->at(i)); | 3843 VisitForStackValue(args->at(i)); |
| 3842 } | 3844 } |
| 3843 | 3845 |
| 3844 if (expr->is_jsruntime()) { | 3846 if (expr->is_jsruntime()) { |
| 3845 // Call the JS runtime function. | 3847 // Call the JS runtime function. |
| 3846 __ mov(r2, Operand(expr->name())); | 3848 __ mov(r2, Operand(expr->name())); |
| 3847 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 3849 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
| 3848 Handle<Code> ic = | 3850 Handle<Code> ic = |
| 3849 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 3851 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 3850 CallIC(ic, mode, expr->id()); | 3852 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
| 3851 // Restore context register. | 3853 // Restore context register. |
| 3852 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3854 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3853 } else { | 3855 } else { |
| 3854 // Call the C runtime function. | 3856 // Call the C runtime function. |
| 3855 __ CallRuntime(expr->function(), arg_count); | 3857 __ CallRuntime(expr->function(), arg_count); |
| 3856 } | 3858 } |
| 3857 context()->Plug(r0); | 3859 context()->Plug(r0); |
| 3858 } | 3860 } |
| 3859 | 3861 |
| 3860 | 3862 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3995 // TODO(svenpanne): Allowing format strings in Comment would be nice here... | 3997 // TODO(svenpanne): Allowing format strings in Comment would be nice here... |
| 3996 Comment cmt(masm_, comment); | 3998 Comment cmt(masm_, comment); |
| 3997 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 3999 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
| 3998 UnaryOverwriteMode overwrite = | 4000 UnaryOverwriteMode overwrite = |
| 3999 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 4001 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
| 4000 UnaryOpStub stub(expr->op(), overwrite); | 4002 UnaryOpStub stub(expr->op(), overwrite); |
| 4001 // UnaryOpStub expects the argument to be in the | 4003 // UnaryOpStub expects the argument to be in the |
| 4002 // accumulator register r0. | 4004 // accumulator register r0. |
| 4003 VisitForAccumulatorValue(expr->expression()); | 4005 VisitForAccumulatorValue(expr->expression()); |
| 4004 SetSourcePosition(expr->position()); | 4006 SetSourcePosition(expr->position()); |
| 4005 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 4007 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, |
| 4008 expr->UnaryOperationFeedbackId()); |
| 4006 context()->Plug(r0); | 4009 context()->Plug(r0); |
| 4007 } | 4010 } |
| 4008 | 4011 |
| 4009 | 4012 |
| 4010 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4013 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4011 Comment cmnt(masm_, "[ CountOperation"); | 4014 Comment cmnt(masm_, "[ CountOperation"); |
| 4012 SetSourcePosition(expr->position()); | 4015 SetSourcePosition(expr->position()); |
| 4013 | 4016 |
| 4014 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' | 4017 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' |
| 4015 // as the left-hand side. | 4018 // as the left-hand side. |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4106 __ bind(&stub_call); | 4109 __ bind(&stub_call); |
| 4107 // Call stub. Undo operation first. | 4110 // Call stub. Undo operation first. |
| 4108 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); | 4111 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); |
| 4109 } | 4112 } |
| 4110 __ mov(r1, Operand(Smi::FromInt(count_value))); | 4113 __ mov(r1, Operand(Smi::FromInt(count_value))); |
| 4111 | 4114 |
| 4112 // Record position before stub call. | 4115 // Record position before stub call. |
| 4113 SetSourcePosition(expr->position()); | 4116 SetSourcePosition(expr->position()); |
| 4114 | 4117 |
| 4115 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); | 4118 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); |
| 4116 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); | 4119 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountBinOpFeedbackId()); |
| 4117 patch_site.EmitPatchInfo(); | 4120 patch_site.EmitPatchInfo(); |
| 4118 __ bind(&done); | 4121 __ bind(&done); |
| 4119 | 4122 |
| 4120 // Store the value returned in r0. | 4123 // Store the value returned in r0. |
| 4121 switch (assign_type) { | 4124 switch (assign_type) { |
| 4122 case VARIABLE: | 4125 case VARIABLE: |
| 4123 if (expr->is_postfix()) { | 4126 if (expr->is_postfix()) { |
| 4124 { EffectContext context(this); | 4127 { EffectContext context(this); |
| 4125 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4128 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4126 Token::ASSIGN); | 4129 Token::ASSIGN); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4138 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4141 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4139 context()->Plug(r0); | 4142 context()->Plug(r0); |
| 4140 } | 4143 } |
| 4141 break; | 4144 break; |
| 4142 case NAMED_PROPERTY: { | 4145 case NAMED_PROPERTY: { |
| 4143 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 4146 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 4144 __ pop(r1); | 4147 __ pop(r1); |
| 4145 Handle<Code> ic = is_classic_mode() | 4148 Handle<Code> ic = is_classic_mode() |
| 4146 ? isolate()->builtins()->StoreIC_Initialize() | 4149 ? isolate()->builtins()->StoreIC_Initialize() |
| 4147 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 4150 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
| 4148 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4151 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); |
| 4149 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4152 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4150 if (expr->is_postfix()) { | 4153 if (expr->is_postfix()) { |
| 4151 if (!context()->IsEffect()) { | 4154 if (!context()->IsEffect()) { |
| 4152 context()->PlugTOS(); | 4155 context()->PlugTOS(); |
| 4153 } | 4156 } |
| 4154 } else { | 4157 } else { |
| 4155 context()->Plug(r0); | 4158 context()->Plug(r0); |
| 4156 } | 4159 } |
| 4157 break; | 4160 break; |
| 4158 } | 4161 } |
| 4159 case KEYED_PROPERTY: { | 4162 case KEYED_PROPERTY: { |
| 4160 __ pop(r1); // Key. | 4163 __ pop(r1); // Key. |
| 4161 __ pop(r2); // Receiver. | 4164 __ pop(r2); // Receiver. |
| 4162 Handle<Code> ic = is_classic_mode() | 4165 Handle<Code> ic = is_classic_mode() |
| 4163 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4166 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 4164 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4167 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 4165 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4168 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); |
| 4166 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4169 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4167 if (expr->is_postfix()) { | 4170 if (expr->is_postfix()) { |
| 4168 if (!context()->IsEffect()) { | 4171 if (!context()->IsEffect()) { |
| 4169 context()->PlugTOS(); | 4172 context()->PlugTOS(); |
| 4170 } | 4173 } |
| 4171 } else { | 4174 } else { |
| 4172 context()->Plug(r0); | 4175 context()->Plug(r0); |
| 4173 } | 4176 } |
| 4174 break; | 4177 break; |
| 4175 } | 4178 } |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4364 __ orr(r2, r0, Operand(r1)); | 4367 __ orr(r2, r0, Operand(r1)); |
| 4365 patch_site.EmitJumpIfNotSmi(r2, &slow_case); | 4368 patch_site.EmitJumpIfNotSmi(r2, &slow_case); |
| 4366 __ cmp(r1, r0); | 4369 __ cmp(r1, r0); |
| 4367 Split(cond, if_true, if_false, NULL); | 4370 Split(cond, if_true, if_false, NULL); |
| 4368 __ bind(&slow_case); | 4371 __ bind(&slow_case); |
| 4369 } | 4372 } |
| 4370 | 4373 |
| 4371 // Record position and call the compare IC. | 4374 // Record position and call the compare IC. |
| 4372 SetSourcePosition(expr->position()); | 4375 SetSourcePosition(expr->position()); |
| 4373 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4376 Handle<Code> ic = CompareIC::GetUninitialized(op); |
| 4374 CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4377 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); |
| 4375 patch_site.EmitPatchInfo(); | 4378 patch_site.EmitPatchInfo(); |
| 4376 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4379 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4377 __ cmp(r0, Operand(0)); | 4380 __ cmp(r0, Operand(0)); |
| 4378 Split(cond, if_true, if_false, fall_through); | 4381 Split(cond, if_true, if_false, fall_through); |
| 4379 } | 4382 } |
| 4380 } | 4383 } |
| 4381 | 4384 |
| 4382 // Convert the result of the comparison into one expected for this | 4385 // Convert the result of the comparison into one expected for this |
| 4383 // expression's context. | 4386 // expression's context. |
| 4384 context()->Plug(if_true, if_false); | 4387 context()->Plug(if_true, if_false); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4570 *context_length = 0; | 4573 *context_length = 0; |
| 4571 return previous_; | 4574 return previous_; |
| 4572 } | 4575 } |
| 4573 | 4576 |
| 4574 | 4577 |
| 4575 #undef __ | 4578 #undef __ |
| 4576 | 4579 |
| 4577 } } // namespace v8::internal | 4580 } } // namespace v8::internal |
| 4578 | 4581 |
| 4579 #endif // V8_TARGET_ARCH_ARM | 4582 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |