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 3213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3224 | 3224 |
3225 __ bind(&miss); | 3225 __ bind(&miss); |
3226 GenerateMiss(masm); | 3226 GenerateMiss(masm); |
3227 } | 3227 } |
3228 | 3228 |
3229 | 3229 |
3230 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 3230 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
3231 // Cache the called function in a global property cell. Cache states | 3231 // Cache the called function in a global property cell. Cache states |
3232 // are uninitialized, monomorphic (indicated by a JSFunction), and | 3232 // are uninitialized, monomorphic (indicated by a JSFunction), and |
3233 // megamorphic. | 3233 // megamorphic. |
| 3234 // rax : number of arguments to the construct function |
3234 // rbx : cache cell for call target | 3235 // rbx : cache cell for call target |
3235 // rdi : the function to call | 3236 // rdi : the function to call |
3236 Isolate* isolate = masm->isolate(); | 3237 Isolate* isolate = masm->isolate(); |
3237 Label initialize, done, miss, megamorphic, not_array_function; | 3238 Label initialize, done, miss, megamorphic, not_array_function; |
3238 | 3239 |
3239 // Load the cache state into rcx. | 3240 // Load the cache state into rcx. |
3240 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset)); | 3241 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset)); |
3241 | 3242 |
3242 // A monomorphic cache hit or an already megamorphic state: invoke the | 3243 // A monomorphic cache hit or an already megamorphic state: invoke the |
3243 // function without changing the state. | 3244 // function without changing the state. |
3244 __ cmpq(rcx, rdi); | 3245 __ cmpq(rcx, rdi); |
3245 __ j(equal, &done); | 3246 __ j(equal, &done); |
3246 __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate)); | 3247 __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate)); |
3247 __ j(equal, &done); | 3248 __ j(equal, &done); |
3248 | 3249 |
3249 // If we came here, we need to see if we are the array function. | 3250 // If we came here, we need to see if we are the array function. |
3250 // If we didn't have a matching function, and we didn't find the megamorph | 3251 // If we didn't have a matching function, and we didn't find the megamorph |
3251 // sentinel, then we have in the cell either some other function or an | 3252 // sentinel, then we have in the cell either some other function or an |
3252 // AllocationSite. Do a map check on the object in rcx. | 3253 // AllocationSite. Do a map check on the object in rcx. |
3253 Handle<Map> allocation_site_map( | 3254 Handle<Map> allocation_site_map = |
3254 masm->isolate()->heap()->allocation_site_map(), | 3255 masm->isolate()->factory()->allocation_site_map(); |
3255 masm->isolate()); | |
3256 __ Cmp(FieldOperand(rcx, 0), allocation_site_map); | 3256 __ Cmp(FieldOperand(rcx, 0), allocation_site_map); |
3257 __ j(not_equal, &miss); | 3257 __ j(not_equal, &miss); |
3258 | 3258 |
3259 // Make sure the function is the Array() function | 3259 // Make sure the function is the Array() function |
3260 __ LoadArrayFunction(rcx); | 3260 __ LoadArrayFunction(rcx); |
3261 __ cmpq(rdi, rcx); | 3261 __ cmpq(rdi, rcx); |
3262 __ j(not_equal, &megamorphic); | 3262 __ j(not_equal, &megamorphic); |
3263 __ jmp(&done); | 3263 __ jmp(&done); |
3264 | 3264 |
3265 __ bind(&miss); | 3265 __ bind(&miss); |
(...skipping 15 matching lines...) Expand all Loading... |
3281 // Make sure the function is the Array() function | 3281 // Make sure the function is the Array() function |
3282 __ LoadArrayFunction(rcx); | 3282 __ LoadArrayFunction(rcx); |
3283 __ cmpq(rdi, rcx); | 3283 __ cmpq(rdi, rcx); |
3284 __ j(not_equal, ¬_array_function); | 3284 __ j(not_equal, ¬_array_function); |
3285 | 3285 |
3286 // The target function is the Array constructor, | 3286 // The target function is the Array constructor, |
3287 // Create an AllocationSite if we don't already have it, store it in the cell | 3287 // Create an AllocationSite if we don't already have it, store it in the cell |
3288 { | 3288 { |
3289 FrameScope scope(masm, StackFrame::INTERNAL); | 3289 FrameScope scope(masm, StackFrame::INTERNAL); |
3290 | 3290 |
| 3291 // Arguments register must be smi-tagged to call out. |
3291 __ Integer32ToSmi(rax, rax); | 3292 __ Integer32ToSmi(rax, rax); |
3292 __ push(rax); | 3293 __ push(rax); |
3293 __ push(rdi); | 3294 __ push(rdi); |
3294 __ push(rbx); | 3295 __ push(rbx); |
3295 | 3296 |
3296 CreateAllocationSiteStub create_stub; | 3297 CreateAllocationSiteStub create_stub; |
3297 __ CallStub(&create_stub); | 3298 __ CallStub(&create_stub); |
3298 | 3299 |
3299 __ pop(rbx); | 3300 __ pop(rbx); |
3300 __ pop(rdi); | 3301 __ pop(rdi); |
(...skipping 2989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6290 ArraySingleArgumentConstructorStub stub(initial, | 6291 ArraySingleArgumentConstructorStub stub(initial, |
6291 CONTEXT_CHECK_REQUIRED, | 6292 CONTEXT_CHECK_REQUIRED, |
6292 DISABLE_ALLOCATION_SITES); | 6293 DISABLE_ALLOCATION_SITES); |
6293 __ TailCallStub(&stub); | 6294 __ TailCallStub(&stub); |
6294 } else if (mode == DONT_OVERRIDE) { | 6295 } else if (mode == DONT_OVERRIDE) { |
6295 // We are going to create a holey array, but our kind is non-holey. | 6296 // We are going to create a holey array, but our kind is non-holey. |
6296 // Fix kind and retry (only if we have an allocation site in the cell). | 6297 // Fix kind and retry (only if we have an allocation site in the cell). |
6297 __ incl(rdx); | 6298 __ incl(rdx); |
6298 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset)); | 6299 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset)); |
6299 if (FLAG_debug_code) { | 6300 if (FLAG_debug_code) { |
6300 Handle<Map> allocation_site_map( | 6301 Handle<Map> allocation_site_map = |
6301 masm->isolate()->heap()->allocation_site_map(), | 6302 masm->isolate()->factory()->allocation_site_map(); |
6302 masm->isolate()); | |
6303 __ Cmp(FieldOperand(rcx, 0), allocation_site_map); | 6303 __ Cmp(FieldOperand(rcx, 0), allocation_site_map); |
6304 __ Assert(equal, kExpectedAllocationSiteInCell); | 6304 __ Assert(equal, kExpectedAllocationSiteInCell); |
6305 } | 6305 } |
6306 | 6306 |
6307 // Save the resulting elements kind in type info | 6307 // Save the resulting elements kind in type info |
6308 __ Integer32ToSmi(rdx, rdx); | 6308 __ Integer32ToSmi(rdx, rdx); |
6309 __ movq(FieldOperand(rcx, AllocationSite::kTransitionInfoOffset), rdx); | 6309 __ movq(FieldOperand(rcx, AllocationSite::kTransitionInfoOffset), rdx); |
6310 __ SmiToInteger32(rdx, rdx); | 6310 __ SmiToInteger32(rdx, rdx); |
6311 | 6311 |
6312 __ bind(&normal_sequence); | 6312 __ bind(&normal_sequence); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6439 __ bind(&okay_here); | 6439 __ bind(&okay_here); |
6440 } | 6440 } |
6441 | 6441 |
6442 Label no_info; | 6442 Label no_info; |
6443 // If the type cell is undefined, or contains anything other than an | 6443 // If the type cell is undefined, or contains anything other than an |
6444 // AllocationSite, call an array constructor that doesn't use AllocationSites. | 6444 // AllocationSite, call an array constructor that doesn't use AllocationSites. |
6445 __ Cmp(rbx, undefined_sentinel); | 6445 __ Cmp(rbx, undefined_sentinel); |
6446 __ j(equal, &no_info); | 6446 __ j(equal, &no_info); |
6447 __ movq(rdx, FieldOperand(rbx, Cell::kValueOffset)); | 6447 __ movq(rdx, FieldOperand(rbx, Cell::kValueOffset)); |
6448 __ Cmp(FieldOperand(rdx, 0), | 6448 __ Cmp(FieldOperand(rdx, 0), |
6449 Handle<Map>(masm->isolate()->heap()->allocation_site_map())); | 6449 masm->isolate()->factory()->allocation_site_map()); |
6450 __ j(not_equal, &no_info); | 6450 __ j(not_equal, &no_info); |
6451 | 6451 |
6452 __ movq(rdx, FieldOperand(rdx, AllocationSite::kTransitionInfoOffset)); | 6452 __ movq(rdx, FieldOperand(rdx, AllocationSite::kTransitionInfoOffset)); |
6453 __ SmiToInteger32(rdx, rdx); | 6453 __ SmiToInteger32(rdx, rdx); |
6454 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 6454 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
6455 | 6455 |
6456 __ bind(&no_info); | 6456 __ bind(&no_info); |
6457 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 6457 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
6458 } | 6458 } |
6459 | 6459 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6546 __ bind(&fast_elements_case); | 6546 __ bind(&fast_elements_case); |
6547 GenerateCase(masm, FAST_ELEMENTS); | 6547 GenerateCase(masm, FAST_ELEMENTS); |
6548 } | 6548 } |
6549 | 6549 |
6550 | 6550 |
6551 #undef __ | 6551 #undef __ |
6552 | 6552 |
6553 } } // namespace v8::internal | 6553 } } // namespace v8::internal |
6554 | 6554 |
6555 #endif // V8_TARGET_ARCH_X64 | 6555 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |