| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 2249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2260 | 2260 |
| 2261 __ bind(&done); | 2261 __ bind(&done); |
| 2262 __ Integer32ToSmi(rdx, rdx); | 2262 __ Integer32ToSmi(rdx, rdx); |
| 2263 | 2263 |
| 2264 __ bind(&done_no_smi_convert); | 2264 __ bind(&done_no_smi_convert); |
| 2265 } | 2265 } |
| 2266 | 2266 |
| 2267 | 2267 |
| 2268 void CallFunctionStub::Generate(MacroAssembler* masm) { | 2268 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| 2269 // rbx : feedback vector | 2269 // rbx : feedback vector |
| 2270 // rdx : (only if rbx is not undefined) slot in feedback vector (Smi) | 2270 // rdx : (only if rbx is not the megamorphic symbol) slot in feedback |
| 2271 // vector (Smi) |
| 2271 // rdi : the function to call | 2272 // rdi : the function to call |
| 2272 Isolate* isolate = masm->isolate(); | 2273 Isolate* isolate = masm->isolate(); |
| 2273 Label slow, non_function, wrap, cont; | 2274 Label slow, non_function, wrap, cont; |
| 2274 StackArgumentsAccessor args(rsp, argc_); | 2275 StackArgumentsAccessor args(rsp, argc_); |
| 2275 | 2276 |
| 2276 if (NeedsChecks()) { | 2277 if (NeedsChecks()) { |
| 2277 // Check that the function really is a JavaScript function. | 2278 // Check that the function really is a JavaScript function. |
| 2278 __ JumpIfSmi(rdi, &non_function); | 2279 __ JumpIfSmi(rdi, &non_function); |
| 2279 | 2280 |
| 2280 // Goto slow case if we do not have a function. | 2281 // Goto slow case if we do not have a function. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2320 __ bind(&cont); | 2321 __ bind(&cont); |
| 2321 } | 2322 } |
| 2322 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper()); | 2323 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 2323 | 2324 |
| 2324 if (NeedsChecks()) { | 2325 if (NeedsChecks()) { |
| 2325 // Slow-case: Non-function called. | 2326 // Slow-case: Non-function called. |
| 2326 __ bind(&slow); | 2327 __ bind(&slow); |
| 2327 if (RecordCallTarget()) { | 2328 if (RecordCallTarget()) { |
| 2328 // If there is a call target cache, mark it megamorphic in the | 2329 // If there is a call target cache, mark it megamorphic in the |
| 2329 // non-function case. MegamorphicSentinel is an immortal immovable | 2330 // non-function case. MegamorphicSentinel is an immortal immovable |
| 2330 // object (undefined) so no write barrier is needed. | 2331 // object (megamorphic symbol) so no write barrier is needed. |
| 2331 __ SmiToInteger32(rdx, rdx); | 2332 __ SmiToInteger32(rdx, rdx); |
| 2332 __ Move(FieldOperand(rbx, rdx, times_pointer_size, | 2333 __ Move(FieldOperand(rbx, rdx, times_pointer_size, |
| 2333 FixedArray::kHeaderSize), | 2334 FixedArray::kHeaderSize), |
| 2334 TypeFeedbackInfo::MegamorphicSentinel(isolate)); | 2335 TypeFeedbackInfo::MegamorphicSentinel(isolate)); |
| 2335 __ Integer32ToSmi(rdx, rdx); | 2336 __ Integer32ToSmi(rdx, rdx); |
| 2336 } | 2337 } |
| 2337 // Check for function proxy. | 2338 // Check for function proxy. |
| 2338 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); | 2339 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); |
| 2339 __ j(not_equal, &non_function); | 2340 __ j(not_equal, &non_function); |
| 2340 __ PopReturnAddressTo(rcx); | 2341 __ PopReturnAddressTo(rcx); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2372 } | 2373 } |
| 2373 __ movp(args.GetReceiverOperand(), rax); | 2374 __ movp(args.GetReceiverOperand(), rax); |
| 2374 __ jmp(&cont); | 2375 __ jmp(&cont); |
| 2375 } | 2376 } |
| 2376 } | 2377 } |
| 2377 | 2378 |
| 2378 | 2379 |
| 2379 void CallConstructStub::Generate(MacroAssembler* masm) { | 2380 void CallConstructStub::Generate(MacroAssembler* masm) { |
| 2380 // rax : number of arguments | 2381 // rax : number of arguments |
| 2381 // rbx : feedback vector | 2382 // rbx : feedback vector |
| 2382 // rdx : (only if rbx is not undefined) slot in feedback vector (Smi) | 2383 // rdx : (only if rbx is not the megamorphic symbol) slot in feedback |
| 2384 // vector (Smi) |
| 2383 // rdi : constructor function | 2385 // rdi : constructor function |
| 2384 Label slow, non_function_call; | 2386 Label slow, non_function_call; |
| 2385 | 2387 |
| 2386 // Check that function is not a smi. | 2388 // Check that function is not a smi. |
| 2387 __ JumpIfSmi(rdi, &non_function_call); | 2389 __ JumpIfSmi(rdi, &non_function_call); |
| 2388 // Check that function is a JSFunction. | 2390 // Check that function is a JSFunction. |
| 2389 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); | 2391 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
| 2390 __ j(not_equal, &slow); | 2392 __ j(not_equal, &slow); |
| 2391 | 2393 |
| 2392 if (RecordCallTarget()) { | 2394 if (RecordCallTarget()) { |
| (...skipping 2603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4996 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); | 4998 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
| 4997 } else { | 4999 } else { |
| 4998 UNREACHABLE(); | 5000 UNREACHABLE(); |
| 4999 } | 5001 } |
| 5000 } | 5002 } |
| 5001 | 5003 |
| 5002 | 5004 |
| 5003 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 5005 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 5004 // ----------- S t a t e ------------- | 5006 // ----------- S t a t e ------------- |
| 5005 // -- rax : argc | 5007 // -- rax : argc |
| 5006 // -- rbx : feedback vector (fixed array or undefined) | 5008 // -- rbx : feedback vector (fixed array or megamorphic symbol) |
| 5007 // -- rdx : slot index (if ebx is fixed array) | 5009 // -- rdx : slot index (if ebx is fixed array) |
| 5008 // -- rdi : constructor | 5010 // -- rdi : constructor |
| 5009 // -- rsp[0] : return address | 5011 // -- rsp[0] : return address |
| 5010 // -- rsp[8] : last argument | 5012 // -- rsp[8] : last argument |
| 5011 // ----------------------------------- | 5013 // ----------------------------------- |
| 5012 Handle<Object> undefined_sentinel( | 5014 Handle<Object> megamorphic_sentinel = |
| 5013 masm->isolate()->heap()->undefined_value(), | 5015 TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()); |
| 5014 masm->isolate()); | |
| 5015 | 5016 |
| 5016 if (FLAG_debug_code) { | 5017 if (FLAG_debug_code) { |
| 5017 // The array construct code is only set for the global and natives | 5018 // The array construct code is only set for the global and natives |
| 5018 // builtin Array functions which always have maps. | 5019 // builtin Array functions which always have maps. |
| 5019 | 5020 |
| 5020 // Initial map for the builtin Array function should be a map. | 5021 // Initial map for the builtin Array function should be a map. |
| 5021 __ movp(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); | 5022 __ movp(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 5022 // Will both indicate a NULL and a Smi. | 5023 // Will both indicate a NULL and a Smi. |
| 5023 STATIC_ASSERT(kSmiTag == 0); | 5024 STATIC_ASSERT(kSmiTag == 0); |
| 5024 Condition not_smi = NegateCondition(masm->CheckSmi(rcx)); | 5025 Condition not_smi = NegateCondition(masm->CheckSmi(rcx)); |
| 5025 __ Check(not_smi, kUnexpectedInitialMapForArrayFunction); | 5026 __ Check(not_smi, kUnexpectedInitialMapForArrayFunction); |
| 5026 __ CmpObjectType(rcx, MAP_TYPE, rcx); | 5027 __ CmpObjectType(rcx, MAP_TYPE, rcx); |
| 5027 __ Check(equal, kUnexpectedInitialMapForArrayFunction); | 5028 __ Check(equal, kUnexpectedInitialMapForArrayFunction); |
| 5028 | 5029 |
| 5029 // We should either have undefined in rbx or a valid fixed array. | 5030 // We should either have the megamorphic symbol in rbx or a valid |
| 5031 // fixed array. |
| 5030 Label okay_here; | 5032 Label okay_here; |
| 5031 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); | 5033 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); |
| 5032 __ Cmp(rbx, undefined_sentinel); | 5034 __ Cmp(rbx, megamorphic_sentinel); |
| 5033 __ j(equal, &okay_here); | 5035 __ j(equal, &okay_here); |
| 5034 __ Cmp(FieldOperand(rbx, 0), fixed_array_map); | 5036 __ Cmp(FieldOperand(rbx, 0), fixed_array_map); |
| 5035 __ Assert(equal, kExpectedFixedArrayInRegisterRbx); | 5037 __ Assert(equal, kExpectedFixedArrayInRegisterRbx); |
| 5036 | 5038 |
| 5037 // rdx should be a smi if we don't have undefined in rbx. | 5039 // rdx should be a smi if we don't have the megamorphic symbol in rbx. |
| 5038 __ AssertSmi(rdx); | 5040 __ AssertSmi(rdx); |
| 5039 | 5041 |
| 5040 __ bind(&okay_here); | 5042 __ bind(&okay_here); |
| 5041 } | 5043 } |
| 5042 | 5044 |
| 5043 Label no_info; | 5045 Label no_info; |
| 5044 // If the feedback slot is undefined, or contains anything other than an | 5046 // If the feedback slot is the megamorphic sentinel, or contains anything |
| 5045 // AllocationSite, call an array constructor that doesn't use AllocationSites. | 5047 // other than an AllocationSite, call an array constructor that doesn't use |
| 5046 __ Cmp(rbx, undefined_sentinel); | 5048 // AllocationSites. |
| 5049 __ Cmp(rbx, megamorphic_sentinel); |
| 5047 __ j(equal, &no_info); | 5050 __ j(equal, &no_info); |
| 5048 __ SmiToInteger32(rdx, rdx); | 5051 __ SmiToInteger32(rdx, rdx); |
| 5049 __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size, | 5052 __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size, |
| 5050 FixedArray::kHeaderSize)); | 5053 FixedArray::kHeaderSize)); |
| 5051 __ Integer32ToSmi(rdx, rdx); | 5054 __ Integer32ToSmi(rdx, rdx); |
| 5052 __ Cmp(FieldOperand(rbx, 0), | 5055 __ Cmp(FieldOperand(rbx, 0), |
| 5053 masm->isolate()->factory()->allocation_site_map()); | 5056 masm->isolate()->factory()->allocation_site_map()); |
| 5054 __ j(not_equal, &no_info); | 5057 __ j(not_equal, &no_info); |
| 5055 | 5058 |
| 5056 // Only look at the lower 16 bits of the transition info. | 5059 // Only look at the lower 16 bits of the transition info. |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5329 return_value_operand, | 5332 return_value_operand, |
| 5330 NULL); | 5333 NULL); |
| 5331 } | 5334 } |
| 5332 | 5335 |
| 5333 | 5336 |
| 5334 #undef __ | 5337 #undef __ |
| 5335 | 5338 |
| 5336 } } // namespace v8::internal | 5339 } } // namespace v8::internal |
| 5337 | 5340 |
| 5338 #endif // V8_TARGET_ARCH_X64 | 5341 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |