| 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 SetFunctionPosition(function()); | 140 SetFunctionPosition(function()); |
| 141 Comment cmnt(masm_, "[ function compiled by full code generator"); | 141 Comment cmnt(masm_, "[ function compiled by full code generator"); |
| 142 | 142 |
| 143 #ifdef DEBUG | 143 #ifdef DEBUG |
| 144 if (strlen(FLAG_stop_at) > 0 && | 144 if (strlen(FLAG_stop_at) > 0 && |
| 145 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 145 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
| 146 __ stop("stop-at"); | 146 __ stop("stop-at"); |
| 147 } | 147 } |
| 148 #endif | 148 #endif |
| 149 | 149 |
| 150 // Strict mode functions need to replace the receiver with undefined |
| 151 // when called as functions (without an explicit receiver |
| 152 // object). t1 is zero for method calls and non-zero for function |
| 153 // calls. |
| 154 if (info->is_strict_mode()) { |
| 155 Label ok; |
| 156 __ Branch(&ok, eq, t1, Operand(zero_reg)); |
| 157 int receiver_offset = scope()->num_parameters() * kPointerSize; |
| 158 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
| 159 __ sw(a2, MemOperand(sp, receiver_offset)); |
| 160 __ bind(&ok); |
| 161 } |
| 162 |
| 150 int locals_count = scope()->num_stack_slots(); | 163 int locals_count = scope()->num_stack_slots(); |
| 151 | 164 |
| 152 __ Push(ra, fp, cp, a1); | 165 __ Push(ra, fp, cp, a1); |
| 153 if (locals_count > 0) { | 166 if (locals_count > 0) { |
| 154 // Load undefined value here, so the value is ready for the loop | 167 // Load undefined value here, so the value is ready for the loop |
| 155 // below. | 168 // below. |
| 156 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 169 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 157 } | 170 } |
| 158 // Adjust fp to point to caller's fp. | 171 // Adjust fp to point to caller's fp. |
| 159 __ Addu(fp, sp, Operand(2 * kPointerSize)); | 172 __ Addu(fp, sp, Operand(2 * kPointerSize)); |
| (...skipping 1938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2098 for (int i = 0; i < arg_count; i++) { | 2111 for (int i = 0; i < arg_count; i++) { |
| 2099 VisitForStackValue(args->at(i)); | 2112 VisitForStackValue(args->at(i)); |
| 2100 } | 2113 } |
| 2101 __ li(a2, Operand(name)); | 2114 __ li(a2, Operand(name)); |
| 2102 } | 2115 } |
| 2103 // Record source position for debugger. | 2116 // Record source position for debugger. |
| 2104 SetSourcePosition(expr->position()); | 2117 SetSourcePosition(expr->position()); |
| 2105 // Call the IC initialization code. | 2118 // Call the IC initialization code. |
| 2106 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2119 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2107 Handle<Code> ic = | 2120 Handle<Code> ic = |
| 2108 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); | 2121 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); |
| 2109 EmitCallIC(ic, mode, expr->id()); | 2122 EmitCallIC(ic, mode, expr->id()); |
| 2110 RecordJSReturnSite(expr); | 2123 RecordJSReturnSite(expr); |
| 2111 // Restore context register. | 2124 // Restore context register. |
| 2112 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2125 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2113 context()->Plug(v0); | 2126 context()->Plug(v0); |
| 2114 } | 2127 } |
| 2115 | 2128 |
| 2116 | 2129 |
| 2117 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2130 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2118 Expression* key, | 2131 Expression* key) { |
| 2119 RelocInfo::Mode mode) { | |
| 2120 // Load the key. | 2132 // Load the key. |
| 2121 VisitForAccumulatorValue(key); | 2133 VisitForAccumulatorValue(key); |
| 2122 | 2134 |
| 2123 // Swap the name of the function and the receiver on the stack to follow | 2135 // Swap the name of the function and the receiver on the stack to follow |
| 2124 // the calling convention for call ICs. | 2136 // the calling convention for call ICs. |
| 2125 __ pop(a1); | 2137 __ pop(a1); |
| 2126 __ push(v0); | 2138 __ push(v0); |
| 2127 __ push(a1); | 2139 __ push(a1); |
| 2128 | 2140 |
| 2129 // Code common for calls using the IC. | 2141 // Code common for calls using the IC. |
| 2130 ZoneList<Expression*>* args = expr->arguments(); | 2142 ZoneList<Expression*>* args = expr->arguments(); |
| 2131 int arg_count = args->length(); | 2143 int arg_count = args->length(); |
| 2132 { PreservePositionScope scope(masm()->positions_recorder()); | 2144 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2133 for (int i = 0; i < arg_count; i++) { | 2145 for (int i = 0; i < arg_count; i++) { |
| 2134 VisitForStackValue(args->at(i)); | 2146 VisitForStackValue(args->at(i)); |
| 2135 } | 2147 } |
| 2136 } | 2148 } |
| 2137 // Record source position for debugger. | 2149 // Record source position for debugger. |
| 2138 SetSourcePosition(expr->position()); | 2150 SetSourcePosition(expr->position()); |
| 2139 // Call the IC initialization code. | 2151 // Call the IC initialization code. |
| 2140 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2152 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2141 Handle<Code> ic = | 2153 Handle<Code> ic = |
| 2142 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); | 2154 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
| 2143 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2155 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
| 2144 EmitCallIC(ic, mode, expr->id()); | 2156 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 2145 RecordJSReturnSite(expr); | 2157 RecordJSReturnSite(expr); |
| 2146 // Restore context register. | 2158 // Restore context register. |
| 2147 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2159 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2148 context()->DropAndPlug(1, v0); // Drop the key still on the stack. | 2160 context()->DropAndPlug(1, v0); // Drop the key still on the stack. |
| 2149 } | 2161 } |
| 2150 | 2162 |
| 2151 | 2163 |
| 2152 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2164 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| 2153 // Code common for calls using the call stub. | 2165 // Code common for calls using the call stub. |
| 2154 ZoneList<Expression*>* args = expr->arguments(); | 2166 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2248 } | 2260 } |
| 2249 | 2261 |
| 2250 // The runtime call returns a pair of values in v0 (function) and | 2262 // The runtime call returns a pair of values in v0 (function) and |
| 2251 // v1 (receiver). Touch up the stack with the right values. | 2263 // v1 (receiver). Touch up the stack with the right values. |
| 2252 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2264 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2253 __ sw(v1, MemOperand(sp, arg_count * kPointerSize)); | 2265 __ sw(v1, MemOperand(sp, arg_count * kPointerSize)); |
| 2254 } | 2266 } |
| 2255 // Record source position for debugger. | 2267 // Record source position for debugger. |
| 2256 SetSourcePosition(expr->position()); | 2268 SetSourcePosition(expr->position()); |
| 2257 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2269 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2258 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 2270 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT); |
| 2259 __ CallStub(&stub); | 2271 __ CallStub(&stub); |
| 2260 RecordJSReturnSite(expr); | 2272 RecordJSReturnSite(expr); |
| 2261 // Restore context register. | 2273 // Restore context register. |
| 2262 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2274 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2263 context()->DropAndPlug(1, v0); | 2275 context()->DropAndPlug(1, v0); |
| 2264 } else if (var != NULL && !var->is_this() && var->is_global()) { | 2276 } else if (var != NULL && !var->is_this() && var->is_global()) { |
| 2265 // Push global object as receiver for the call IC. | 2277 // Push global object as receiver for the call IC. |
| 2266 __ lw(a0, GlobalObjectOperand()); | 2278 __ lw(a0, GlobalObjectOperand()); |
| 2267 __ push(a0); | 2279 __ push(a0); |
| 2268 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2280 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2298 __ bind(&done); | 2310 __ bind(&done); |
| 2299 // Push function. | 2311 // Push function. |
| 2300 __ push(v0); | 2312 __ push(v0); |
| 2301 // Push global receiver. | 2313 // Push global receiver. |
| 2302 __ lw(a1, GlobalObjectOperand()); | 2314 __ lw(a1, GlobalObjectOperand()); |
| 2303 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2315 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
| 2304 __ push(a1); | 2316 __ push(a1); |
| 2305 __ bind(&call); | 2317 __ bind(&call); |
| 2306 } | 2318 } |
| 2307 | 2319 |
| 2308 // The receiver is either the global receiver or a JSObject found by | 2320 // The receiver is either the global receiver or an object found |
| 2309 // LoadContextSlot. | 2321 // by LoadContextSlot. That object could be the hole if the |
| 2310 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2322 // receiver is implicitly the global object. |
| 2323 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); |
| 2311 } else if (fun->AsProperty() != NULL) { | 2324 } else if (fun->AsProperty() != NULL) { |
| 2312 // Call to an object property. | 2325 // Call to an object property. |
| 2313 Property* prop = fun->AsProperty(); | 2326 Property* prop = fun->AsProperty(); |
| 2314 Literal* key = prop->key()->AsLiteral(); | 2327 Literal* key = prop->key()->AsLiteral(); |
| 2315 if (key != NULL && key->handle()->IsSymbol()) { | 2328 if (key != NULL && key->handle()->IsSymbol()) { |
| 2316 // Call to a named property, use call IC. | 2329 // Call to a named property, use call IC. |
| 2317 { PreservePositionScope scope(masm()->positions_recorder()); | 2330 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2318 VisitForStackValue(prop->obj()); | 2331 VisitForStackValue(prop->obj()); |
| 2319 } | 2332 } |
| 2320 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 2333 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2341 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2354 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2342 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 2355 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 2343 __ lw(a1, GlobalObjectOperand()); | 2356 __ lw(a1, GlobalObjectOperand()); |
| 2344 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2357 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
| 2345 __ Push(v0, a1); // Function, receiver. | 2358 __ Push(v0, a1); // Function, receiver. |
| 2346 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2359 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
| 2347 } else { | 2360 } else { |
| 2348 { PreservePositionScope scope(masm()->positions_recorder()); | 2361 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2349 VisitForStackValue(prop->obj()); | 2362 VisitForStackValue(prop->obj()); |
| 2350 } | 2363 } |
| 2351 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 2364 EmitKeyedCallWithIC(expr, prop->key()); |
| 2352 } | 2365 } |
| 2353 } | 2366 } |
| 2354 } else { | 2367 } else { |
| 2355 { PreservePositionScope scope(masm()->positions_recorder()); | 2368 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2356 VisitForStackValue(fun); | 2369 VisitForStackValue(fun); |
| 2357 } | 2370 } |
| 2358 // Load global receiver object. | 2371 // Load global receiver object. |
| 2359 __ lw(a1, GlobalObjectOperand()); | 2372 __ lw(a1, GlobalObjectOperand()); |
| 2360 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2373 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
| 2361 __ push(a1); | 2374 __ push(a1); |
| (...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3656 | 3669 |
| 3657 // Push the arguments ("left-to-right"). | 3670 // Push the arguments ("left-to-right"). |
| 3658 int arg_count = args->length(); | 3671 int arg_count = args->length(); |
| 3659 for (int i = 0; i < arg_count; i++) { | 3672 for (int i = 0; i < arg_count; i++) { |
| 3660 VisitForStackValue(args->at(i)); | 3673 VisitForStackValue(args->at(i)); |
| 3661 } | 3674 } |
| 3662 | 3675 |
| 3663 if (expr->is_jsruntime()) { | 3676 if (expr->is_jsruntime()) { |
| 3664 // Call the JS runtime function. | 3677 // Call the JS runtime function. |
| 3665 __ li(a2, Operand(expr->name())); | 3678 __ li(a2, Operand(expr->name())); |
| 3679 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
| 3666 Handle<Code> ic = | 3680 Handle<Code> ic = |
| 3667 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); | 3681 isolate()->stub_cache()->ComputeCallInitialize(arg_count, |
| 3668 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 3682 NOT_IN_LOOP, |
| 3683 mode); |
| 3684 EmitCallIC(ic, mode, expr->id()); |
| 3669 // Restore context register. | 3685 // Restore context register. |
| 3670 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3686 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3671 } else { | 3687 } else { |
| 3672 // Call the C runtime function. | 3688 // Call the C runtime function. |
| 3673 __ CallRuntime(expr->function(), arg_count); | 3689 __ CallRuntime(expr->function(), arg_count); |
| 3674 } | 3690 } |
| 3675 context()->Plug(v0); | 3691 context()->Plug(v0); |
| 3676 } | 3692 } |
| 3677 | 3693 |
| 3678 | 3694 |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4363 __ Addu(at, a1, Operand(masm_->CodeObject())); | 4379 __ Addu(at, a1, Operand(masm_->CodeObject())); |
| 4364 __ Jump(at); | 4380 __ Jump(at); |
| 4365 } | 4381 } |
| 4366 | 4382 |
| 4367 | 4383 |
| 4368 #undef __ | 4384 #undef __ |
| 4369 | 4385 |
| 4370 } } // namespace v8::internal | 4386 } } // namespace v8::internal |
| 4371 | 4387 |
| 4372 #endif // V8_TARGET_ARCH_MIPS | 4388 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |