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 2038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2049 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); | 2049 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
2050 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. | 2050 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. |
2051 EmitCallIC(ic, mode, expr->id()); | 2051 EmitCallIC(ic, mode, expr->id()); |
2052 RecordJSReturnSite(expr); | 2052 RecordJSReturnSite(expr); |
2053 // Restore context register. | 2053 // Restore context register. |
2054 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2054 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2055 context()->DropAndPlug(1, rax); // Drop the key still on the stack. | 2055 context()->DropAndPlug(1, rax); // Drop the key still on the stack. |
2056 } | 2056 } |
2057 | 2057 |
2058 | 2058 |
2059 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 2059 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
2060 // Code common for calls using the call stub. | 2060 // Code common for calls using the call stub. |
2061 ZoneList<Expression*>* args = expr->arguments(); | 2061 ZoneList<Expression*>* args = expr->arguments(); |
2062 int arg_count = args->length(); | 2062 int arg_count = args->length(); |
2063 { PreservePositionScope scope(masm()->positions_recorder()); | 2063 { PreservePositionScope scope(masm()->positions_recorder()); |
2064 for (int i = 0; i < arg_count; i++) { | 2064 for (int i = 0; i < arg_count; i++) { |
2065 VisitForStackValue(args->at(i)); | 2065 VisitForStackValue(args->at(i)); |
2066 } | 2066 } |
2067 } | 2067 } |
2068 // Record source position for debugger. | 2068 // Record source position for debugger. |
2069 SetSourcePosition(expr->position()); | 2069 SetSourcePosition(expr->position()); |
2070 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2070 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2071 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 2071 CallFunctionStub stub(arg_count, in_loop, flags); |
2072 __ CallStub(&stub); | 2072 __ CallStub(&stub); |
2073 RecordJSReturnSite(expr); | 2073 RecordJSReturnSite(expr); |
2074 // Restore context register. | 2074 // Restore context register. |
2075 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2075 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2076 // Discard the function left on TOS. | 2076 // Discard the function left on TOS. |
2077 context()->DropAndPlug(1, rax); | 2077 context()->DropAndPlug(1, rax); |
2078 } | 2078 } |
2079 | 2079 |
2080 | 2080 |
2081 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, | 2081 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2196 // If fast case code has been generated, emit code to push the | 2196 // If fast case code has been generated, emit code to push the |
2197 // function and receiver and have the slow path jump around this | 2197 // function and receiver and have the slow path jump around this |
2198 // code. | 2198 // code. |
2199 if (done.is_linked()) { | 2199 if (done.is_linked()) { |
2200 NearLabel call; | 2200 NearLabel call; |
2201 __ jmp(&call); | 2201 __ jmp(&call); |
2202 __ bind(&done); | 2202 __ bind(&done); |
2203 // Push function. | 2203 // Push function. |
2204 __ push(rax); | 2204 __ push(rax); |
2205 // Push global receiver. | 2205 // Push global receiver. |
2206 __ movq(rbx, GlobalObjectOperand()); | 2206 __ movq(rbx, GlobalObjectOperand()); |
2207 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 2207 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
2208 __ bind(&call); | 2208 __ bind(&call); |
2209 } | 2209 } |
2210 | 2210 |
2211 EmitCallWithStub(expr); | 2211 // The receiver is either the global receiver or a JSObject found by |
| 2212 // LoadContextSlot. |
| 2213 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
2212 } else if (fun->AsProperty() != NULL) { | 2214 } else if (fun->AsProperty() != NULL) { |
2213 // Call to an object property. | 2215 // Call to an object property. |
2214 Property* prop = fun->AsProperty(); | 2216 Property* prop = fun->AsProperty(); |
2215 Literal* key = prop->key()->AsLiteral(); | 2217 Literal* key = prop->key()->AsLiteral(); |
2216 if (key != NULL && key->handle()->IsSymbol()) { | 2218 if (key != NULL && key->handle()->IsSymbol()) { |
2217 // Call to a named property, use call IC. | 2219 // Call to a named property, use call IC. |
2218 { PreservePositionScope scope(masm()->positions_recorder()); | 2220 { PreservePositionScope scope(masm()->positions_recorder()); |
2219 VisitForStackValue(prop->obj()); | 2221 VisitForStackValue(prop->obj()); |
2220 } | 2222 } |
2221 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 2223 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
(...skipping 17 matching lines...) Expand all Loading... |
2239 // Record source code position for IC call. | 2241 // Record source code position for IC call. |
2240 SetSourcePosition(prop->position()); | 2242 SetSourcePosition(prop->position()); |
2241 | 2243 |
2242 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2244 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2243 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 2245 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
2244 // Push result (function). | 2246 // Push result (function). |
2245 __ push(rax); | 2247 __ push(rax); |
2246 // Push Global receiver. | 2248 // Push Global receiver. |
2247 __ movq(rcx, GlobalObjectOperand()); | 2249 __ movq(rcx, GlobalObjectOperand()); |
2248 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); | 2250 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); |
2249 EmitCallWithStub(expr); | 2251 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
2250 } else { | 2252 } else { |
2251 { PreservePositionScope scope(masm()->positions_recorder()); | 2253 { PreservePositionScope scope(masm()->positions_recorder()); |
2252 VisitForStackValue(prop->obj()); | 2254 VisitForStackValue(prop->obj()); |
2253 } | 2255 } |
2254 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 2256 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
2255 } | 2257 } |
2256 } | 2258 } |
2257 } else { | 2259 } else { |
2258 { PreservePositionScope scope(masm()->positions_recorder()); | 2260 { PreservePositionScope scope(masm()->positions_recorder()); |
2259 VisitForStackValue(fun); | 2261 VisitForStackValue(fun); |
2260 } | 2262 } |
2261 // Load global receiver object. | 2263 // Load global receiver object. |
2262 __ movq(rbx, GlobalObjectOperand()); | 2264 __ movq(rbx, GlobalObjectOperand()); |
2263 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 2265 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
2264 // Emit function call. | 2266 // Emit function call. |
2265 EmitCallWithStub(expr); | 2267 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
2266 } | 2268 } |
2267 | 2269 |
2268 #ifdef DEBUG | 2270 #ifdef DEBUG |
2269 // RecordJSReturnSite should have been called. | 2271 // RecordJSReturnSite should have been called. |
2270 ASSERT(expr->return_is_recorded_); | 2272 ASSERT(expr->return_is_recorded_); |
2271 #endif | 2273 #endif |
2272 } | 2274 } |
2273 | 2275 |
2274 | 2276 |
2275 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2277 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
(...skipping 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4317 __ ret(0); | 4319 __ ret(0); |
4318 } | 4320 } |
4319 | 4321 |
4320 | 4322 |
4321 #undef __ | 4323 #undef __ |
4322 | 4324 |
4323 | 4325 |
4324 } } // namespace v8::internal | 4326 } } // namespace v8::internal |
4325 | 4327 |
4326 #endif // V8_TARGET_ARCH_X64 | 4328 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |