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 |