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