| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 SetFunctionPosition(function()); | 132 SetFunctionPosition(function()); |
| 133 Comment cmnt(masm_, "[ function compiled by full code generator"); | 133 Comment cmnt(masm_, "[ function compiled by full code generator"); |
| 134 | 134 |
| 135 #ifdef DEBUG | 135 #ifdef DEBUG |
| 136 if (strlen(FLAG_stop_at) > 0 && | 136 if (strlen(FLAG_stop_at) > 0 && |
| 137 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 137 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
| 138 __ stop("stop-at"); | 138 __ stop("stop-at"); |
| 139 } | 139 } |
| 140 #endif | 140 #endif |
| 141 | 141 |
| 142 // Strict mode functions need to replace the receiver with undefined |
| 143 // when called as functions (without an explicit receiver |
| 144 // object). r5 is zero for method calls and non-zero for function |
| 145 // calls. |
| 146 if (info->is_strict_mode()) { |
| 147 Label ok; |
| 148 __ cmp(r5, Operand(0)); |
| 149 __ b(eq, &ok); |
| 150 int receiver_offset = scope()->num_parameters() * kPointerSize; |
| 151 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
| 152 __ str(r2, MemOperand(sp, receiver_offset)); |
| 153 __ bind(&ok); |
| 154 } |
| 155 |
| 142 int locals_count = scope()->num_stack_slots(); | 156 int locals_count = scope()->num_stack_slots(); |
| 143 | 157 |
| 144 __ Push(lr, fp, cp, r1); | 158 __ Push(lr, fp, cp, r1); |
| 145 if (locals_count > 0) { | 159 if (locals_count > 0) { |
| 146 // Load undefined value here, so the value is ready for the loop | 160 // Load undefined value here, so the value is ready for the loop |
| 147 // below. | 161 // below. |
| 148 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 162 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 149 } | 163 } |
| 150 // Adjust fp to point to caller's fp. | 164 // Adjust fp to point to caller's fp. |
| 151 __ add(fp, sp, Operand(2 * kPointerSize)); | 165 __ add(fp, sp, Operand(2 * kPointerSize)); |
| (...skipping 1934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2086 for (int i = 0; i < arg_count; i++) { | 2100 for (int i = 0; i < arg_count; i++) { |
| 2087 VisitForStackValue(args->at(i)); | 2101 VisitForStackValue(args->at(i)); |
| 2088 } | 2102 } |
| 2089 __ mov(r2, Operand(name)); | 2103 __ mov(r2, Operand(name)); |
| 2090 } | 2104 } |
| 2091 // Record source position for debugger. | 2105 // Record source position for debugger. |
| 2092 SetSourcePosition(expr->position()); | 2106 SetSourcePosition(expr->position()); |
| 2093 // Call the IC initialization code. | 2107 // Call the IC initialization code. |
| 2094 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2108 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2095 Handle<Code> ic = | 2109 Handle<Code> ic = |
| 2096 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); | 2110 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); |
| 2097 EmitCallIC(ic, mode, expr->id()); | 2111 EmitCallIC(ic, mode, expr->id()); |
| 2098 RecordJSReturnSite(expr); | 2112 RecordJSReturnSite(expr); |
| 2099 // Restore context register. | 2113 // Restore context register. |
| 2100 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2114 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2101 context()->Plug(r0); | 2115 context()->Plug(r0); |
| 2102 } | 2116 } |
| 2103 | 2117 |
| 2104 | 2118 |
| 2105 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2119 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2106 Expression* key, | 2120 Expression* key) { |
| 2107 RelocInfo::Mode mode) { | |
| 2108 // Load the key. | 2121 // Load the key. |
| 2109 VisitForAccumulatorValue(key); | 2122 VisitForAccumulatorValue(key); |
| 2110 | 2123 |
| 2111 // Swap the name of the function and the receiver on the stack to follow | 2124 // Swap the name of the function and the receiver on the stack to follow |
| 2112 // the calling convention for call ICs. | 2125 // the calling convention for call ICs. |
| 2113 __ pop(r1); | 2126 __ pop(r1); |
| 2114 __ push(r0); | 2127 __ push(r0); |
| 2115 __ push(r1); | 2128 __ push(r1); |
| 2116 | 2129 |
| 2117 // Code common for calls using the IC. | 2130 // Code common for calls using the IC. |
| 2118 ZoneList<Expression*>* args = expr->arguments(); | 2131 ZoneList<Expression*>* args = expr->arguments(); |
| 2119 int arg_count = args->length(); | 2132 int arg_count = args->length(); |
| 2120 { PreservePositionScope scope(masm()->positions_recorder()); | 2133 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2121 for (int i = 0; i < arg_count; i++) { | 2134 for (int i = 0; i < arg_count; i++) { |
| 2122 VisitForStackValue(args->at(i)); | 2135 VisitForStackValue(args->at(i)); |
| 2123 } | 2136 } |
| 2124 } | 2137 } |
| 2125 // Record source position for debugger. | 2138 // Record source position for debugger. |
| 2126 SetSourcePosition(expr->position()); | 2139 SetSourcePosition(expr->position()); |
| 2127 // Call the IC initialization code. | 2140 // Call the IC initialization code. |
| 2128 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2141 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2129 Handle<Code> ic = | 2142 Handle<Code> ic = |
| 2130 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); | 2143 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
| 2131 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2144 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
| 2132 EmitCallIC(ic, mode, expr->id()); | 2145 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 2133 RecordJSReturnSite(expr); | 2146 RecordJSReturnSite(expr); |
| 2134 // Restore context register. | 2147 // Restore context register. |
| 2135 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2148 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2136 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 2149 context()->DropAndPlug(1, r0); // Drop the key still on the stack. |
| 2137 } | 2150 } |
| 2138 | 2151 |
| 2139 | 2152 |
| 2140 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2153 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| 2141 // Code common for calls using the call stub. | 2154 // Code common for calls using the call stub. |
| 2142 ZoneList<Expression*>* args = expr->arguments(); | 2155 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2238 | 2251 |
| 2239 // The runtime call returns a pair of values in r0 (function) and | 2252 // The runtime call returns a pair of values in r0 (function) and |
| 2240 // r1 (receiver). Touch up the stack with the right values. | 2253 // r1 (receiver). Touch up the stack with the right values. |
| 2241 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2254 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2242 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); | 2255 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 2243 } | 2256 } |
| 2244 | 2257 |
| 2245 // Record source position for debugger. | 2258 // Record source position for debugger. |
| 2246 SetSourcePosition(expr->position()); | 2259 SetSourcePosition(expr->position()); |
| 2247 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2260 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2248 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 2261 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT); |
| 2249 __ CallStub(&stub); | 2262 __ CallStub(&stub); |
| 2250 RecordJSReturnSite(expr); | 2263 RecordJSReturnSite(expr); |
| 2251 // Restore context register. | 2264 // Restore context register. |
| 2252 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2265 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2253 context()->DropAndPlug(1, r0); | 2266 context()->DropAndPlug(1, r0); |
| 2254 } else if (var != NULL && !var->is_this() && var->is_global()) { | 2267 } else if (var != NULL && !var->is_this() && var->is_global()) { |
| 2255 // Push global object as receiver for the call IC. | 2268 // Push global object as receiver for the call IC. |
| 2256 __ ldr(r0, GlobalObjectOperand()); | 2269 __ ldr(r0, GlobalObjectOperand()); |
| 2257 __ push(r0); | 2270 __ push(r0); |
| 2258 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2271 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2288 __ bind(&done); | 2301 __ bind(&done); |
| 2289 // Push function. | 2302 // Push function. |
| 2290 __ push(r0); | 2303 __ push(r0); |
| 2291 // Push global receiver. | 2304 // Push global receiver. |
| 2292 __ ldr(r1, GlobalObjectOperand()); | 2305 __ ldr(r1, GlobalObjectOperand()); |
| 2293 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2306 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2294 __ push(r1); | 2307 __ push(r1); |
| 2295 __ bind(&call); | 2308 __ bind(&call); |
| 2296 } | 2309 } |
| 2297 | 2310 |
| 2298 // The receiver is either the global receiver or a JSObject found by | 2311 // The receiver is either the global receiver or an object found |
| 2299 // LoadContextSlot. | 2312 // by LoadContextSlot. That object could be the hole if the |
| 2300 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2313 // receiver is implicitly the global object. |
| 2314 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); |
| 2301 } else if (fun->AsProperty() != NULL) { | 2315 } else if (fun->AsProperty() != NULL) { |
| 2302 // Call to an object property. | 2316 // Call to an object property. |
| 2303 Property* prop = fun->AsProperty(); | 2317 Property* prop = fun->AsProperty(); |
| 2304 Literal* key = prop->key()->AsLiteral(); | 2318 Literal* key = prop->key()->AsLiteral(); |
| 2305 if (key != NULL && key->handle()->IsSymbol()) { | 2319 if (key != NULL && key->handle()->IsSymbol()) { |
| 2306 // Call to a named property, use call IC. | 2320 // Call to a named property, use call IC. |
| 2307 { PreservePositionScope scope(masm()->positions_recorder()); | 2321 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2308 VisitForStackValue(prop->obj()); | 2322 VisitForStackValue(prop->obj()); |
| 2309 } | 2323 } |
| 2310 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 2324 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2331 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2345 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2332 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 2346 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 2333 __ ldr(r1, GlobalObjectOperand()); | 2347 __ ldr(r1, GlobalObjectOperand()); |
| 2334 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2348 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2335 __ Push(r0, r1); // Function, receiver. | 2349 __ Push(r0, r1); // Function, receiver. |
| 2336 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2350 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
| 2337 } else { | 2351 } else { |
| 2338 { PreservePositionScope scope(masm()->positions_recorder()); | 2352 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2339 VisitForStackValue(prop->obj()); | 2353 VisitForStackValue(prop->obj()); |
| 2340 } | 2354 } |
| 2341 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 2355 EmitKeyedCallWithIC(expr, prop->key()); |
| 2342 } | 2356 } |
| 2343 } | 2357 } |
| 2344 } else { | 2358 } else { |
| 2345 { PreservePositionScope scope(masm()->positions_recorder()); | 2359 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2346 VisitForStackValue(fun); | 2360 VisitForStackValue(fun); |
| 2347 } | 2361 } |
| 2348 // Load global receiver object. | 2362 // Load global receiver object. |
| 2349 __ ldr(r1, GlobalObjectOperand()); | 2363 __ ldr(r1, GlobalObjectOperand()); |
| 2350 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2364 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2351 __ push(r1); | 2365 __ push(r1); |
| (...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3640 | 3654 |
| 3641 // Push the arguments ("left-to-right"). | 3655 // Push the arguments ("left-to-right"). |
| 3642 int arg_count = args->length(); | 3656 int arg_count = args->length(); |
| 3643 for (int i = 0; i < arg_count; i++) { | 3657 for (int i = 0; i < arg_count; i++) { |
| 3644 VisitForStackValue(args->at(i)); | 3658 VisitForStackValue(args->at(i)); |
| 3645 } | 3659 } |
| 3646 | 3660 |
| 3647 if (expr->is_jsruntime()) { | 3661 if (expr->is_jsruntime()) { |
| 3648 // Call the JS runtime function. | 3662 // Call the JS runtime function. |
| 3649 __ mov(r2, Operand(expr->name())); | 3663 __ mov(r2, Operand(expr->name())); |
| 3664 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
| 3650 Handle<Code> ic = | 3665 Handle<Code> ic = |
| 3651 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); | 3666 isolate()->stub_cache()->ComputeCallInitialize(arg_count, |
| 3652 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 3667 NOT_IN_LOOP, |
| 3668 mode); |
| 3669 EmitCallIC(ic, mode, expr->id()); |
| 3653 // Restore context register. | 3670 // Restore context register. |
| 3654 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3671 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3655 } else { | 3672 } else { |
| 3656 // Call the C runtime function. | 3673 // Call the C runtime function. |
| 3657 __ CallRuntime(expr->function(), arg_count); | 3674 __ CallRuntime(expr->function(), arg_count); |
| 3658 } | 3675 } |
| 3659 context()->Plug(r0); | 3676 context()->Plug(r0); |
| 3660 } | 3677 } |
| 3661 | 3678 |
| 3662 | 3679 |
| (...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4350 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 4367 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 4351 __ add(pc, r1, Operand(masm_->CodeObject())); | 4368 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 4352 } | 4369 } |
| 4353 | 4370 |
| 4354 | 4371 |
| 4355 #undef __ | 4372 #undef __ |
| 4356 | 4373 |
| 4357 } } // namespace v8::internal | 4374 } } // namespace v8::internal |
| 4358 | 4375 |
| 4359 #endif // V8_TARGET_ARCH_ARM | 4376 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |