| 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 |