OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 4101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4112 | 4112 |
4113 __ bind(&miss); | 4113 __ bind(&miss); |
4114 GenerateMiss(masm); | 4114 GenerateMiss(masm); |
4115 } | 4115 } |
4116 | 4116 |
4117 | 4117 |
4118 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 4118 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
4119 // Cache the called function in a global property cell. Cache states | 4119 // Cache the called function in a global property cell. Cache states |
4120 // are uninitialized, monomorphic (indicated by a JSFunction), and | 4120 // are uninitialized, monomorphic (indicated by a JSFunction), and |
4121 // megamorphic. | 4121 // megamorphic. |
| 4122 // eax : number of arguments to the construct function |
4122 // ebx : cache cell for call target | 4123 // ebx : cache cell for call target |
4123 // edi : the function to call | 4124 // edi : the function to call |
4124 Isolate* isolate = masm->isolate(); | 4125 Isolate* isolate = masm->isolate(); |
4125 Label initialize, done, miss, megamorphic, not_array_function; | 4126 Label initialize, done, miss, megamorphic, not_array_function; |
4126 | 4127 |
4127 // Load the cache state into ecx. | 4128 // Load the cache state into ecx. |
4128 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset)); | 4129 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset)); |
4129 | 4130 |
4130 // A monomorphic cache hit or an already megamorphic state: invoke the | 4131 // A monomorphic cache hit or an already megamorphic state: invoke the |
4131 // function without changing the state. | 4132 // function without changing the state. |
4132 __ cmp(ecx, edi); | 4133 __ cmp(ecx, edi); |
4133 __ j(equal, &done); | 4134 __ j(equal, &done); |
4134 __ cmp(ecx, Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); | 4135 __ cmp(ecx, Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); |
4135 __ j(equal, &done); | 4136 __ j(equal, &done); |
4136 | 4137 |
4137 // If we came here, we need to see if we are the array function. | 4138 // If we came here, we need to see if we are the array function. |
4138 // If we didn't have a matching function, and we didn't find the megamorph | 4139 // If we didn't have a matching function, and we didn't find the megamorph |
4139 // sentinel, then we have in the cell either some other function or an | 4140 // sentinel, then we have in the cell either some other function or an |
4140 // AllocationSite. Do a map check on the object in ecx. | 4141 // AllocationSite. Do a map check on the object in ecx. |
4141 Handle<Map> allocation_site_map( | 4142 Handle<Map> allocation_site_map = |
4142 masm->isolate()->heap()->allocation_site_map(), | 4143 masm->isolate()->factory()->allocation_site_map(); |
4143 masm->isolate()); | |
4144 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); | 4144 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); |
4145 __ j(not_equal, &miss); | 4145 __ j(not_equal, &miss); |
4146 | 4146 |
4147 // Load the global or builtins object from the current context | 4147 // Load the global or builtins object from the current context |
4148 __ LoadGlobalContext(ecx); | 4148 __ LoadGlobalContext(ecx); |
4149 // Make sure the function is the Array() function | 4149 // Make sure the function is the Array() function |
4150 __ cmp(edi, Operand(ecx, | 4150 __ cmp(edi, Operand(ecx, |
4151 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); | 4151 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); |
4152 __ j(not_equal, &megamorphic); | 4152 __ j(not_equal, &megamorphic); |
4153 __ jmp(&done); | 4153 __ jmp(&done); |
(...skipping 18 matching lines...) Expand all Loading... |
4172 // Make sure the function is the Array() function | 4172 // Make sure the function is the Array() function |
4173 __ cmp(edi, Operand(ecx, | 4173 __ cmp(edi, Operand(ecx, |
4174 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); | 4174 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); |
4175 __ j(not_equal, ¬_array_function); | 4175 __ j(not_equal, ¬_array_function); |
4176 | 4176 |
4177 // The target function is the Array constructor, | 4177 // The target function is the Array constructor, |
4178 // Create an AllocationSite if we don't already have it, store it in the cell | 4178 // Create an AllocationSite if we don't already have it, store it in the cell |
4179 { | 4179 { |
4180 FrameScope scope(masm, StackFrame::INTERNAL); | 4180 FrameScope scope(masm, StackFrame::INTERNAL); |
4181 | 4181 |
| 4182 // Arguments register must be smi-tagged to call out. |
4182 __ SmiTag(eax); | 4183 __ SmiTag(eax); |
4183 __ push(eax); | 4184 __ push(eax); |
4184 __ push(edi); | 4185 __ push(edi); |
4185 __ push(ebx); | 4186 __ push(ebx); |
4186 | 4187 |
4187 CreateAllocationSiteStub create_stub; | 4188 CreateAllocationSiteStub create_stub; |
4188 __ CallStub(&create_stub); | 4189 __ CallStub(&create_stub); |
4189 | 4190 |
4190 __ pop(ebx); | 4191 __ pop(ebx); |
4191 __ pop(edi); | 4192 __ pop(edi); |
(...skipping 3012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7204 ArraySingleArgumentConstructorStub stub(initial, | 7205 ArraySingleArgumentConstructorStub stub(initial, |
7205 CONTEXT_CHECK_REQUIRED, | 7206 CONTEXT_CHECK_REQUIRED, |
7206 DISABLE_ALLOCATION_SITES); | 7207 DISABLE_ALLOCATION_SITES); |
7207 __ TailCallStub(&stub); | 7208 __ TailCallStub(&stub); |
7208 } else if (mode == DONT_OVERRIDE) { | 7209 } else if (mode == DONT_OVERRIDE) { |
7209 // We are going to create a holey array, but our kind is non-holey. | 7210 // We are going to create a holey array, but our kind is non-holey. |
7210 // Fix kind and retry. | 7211 // Fix kind and retry. |
7211 __ inc(edx); | 7212 __ inc(edx); |
7212 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset)); | 7213 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset)); |
7213 if (FLAG_debug_code) { | 7214 if (FLAG_debug_code) { |
7214 Handle<Map> allocation_site_map( | 7215 Handle<Map> allocation_site_map = |
7215 masm->isolate()->heap()->allocation_site_map(), | 7216 masm->isolate()->factory()->allocation_site_map(); |
7216 masm->isolate()); | |
7217 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); | 7217 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); |
7218 __ Assert(equal, kExpectedAllocationSiteInCell); | 7218 __ Assert(equal, kExpectedAllocationSiteInCell); |
7219 } | 7219 } |
7220 | 7220 |
7221 // Save the resulting elements kind in type info | 7221 // Save the resulting elements kind in type info |
7222 __ SmiTag(edx); | 7222 __ SmiTag(edx); |
7223 __ mov(FieldOperand(ecx, AllocationSite::kTransitionInfoOffset), edx); | 7223 __ mov(FieldOperand(ecx, AllocationSite::kTransitionInfoOffset), edx); |
7224 __ SmiUntag(edx); | 7224 __ SmiUntag(edx); |
7225 | 7225 |
7226 __ bind(&normal_sequence); | 7226 __ bind(&normal_sequence); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7351 __ Assert(equal, kExpectedPropertyCellInRegisterEbx); | 7351 __ Assert(equal, kExpectedPropertyCellInRegisterEbx); |
7352 __ bind(&okay_here); | 7352 __ bind(&okay_here); |
7353 } | 7353 } |
7354 | 7354 |
7355 Label no_info; | 7355 Label no_info; |
7356 // If the type cell is undefined, or contains anything other than an | 7356 // If the type cell is undefined, or contains anything other than an |
7357 // AllocationSite, call an array constructor that doesn't use AllocationSites. | 7357 // AllocationSite, call an array constructor that doesn't use AllocationSites. |
7358 __ cmp(ebx, Immediate(undefined_sentinel)); | 7358 __ cmp(ebx, Immediate(undefined_sentinel)); |
7359 __ j(equal, &no_info); | 7359 __ j(equal, &no_info); |
7360 __ mov(edx, FieldOperand(ebx, Cell::kValueOffset)); | 7360 __ mov(edx, FieldOperand(ebx, Cell::kValueOffset)); |
7361 __ cmp(FieldOperand(edx, 0), Immediate(Handle<Map>( | 7361 __ cmp(FieldOperand(edx, 0), Immediate( |
7362 masm->isolate()->heap()->allocation_site_map()))); | 7362 masm->isolate()->factory()->allocation_site_map())); |
7363 __ j(not_equal, &no_info); | 7363 __ j(not_equal, &no_info); |
7364 | 7364 |
7365 __ mov(edx, FieldOperand(edx, AllocationSite::kTransitionInfoOffset)); | 7365 __ mov(edx, FieldOperand(edx, AllocationSite::kTransitionInfoOffset)); |
7366 __ SmiUntag(edx); | 7366 __ SmiUntag(edx); |
7367 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 7367 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
7368 | 7368 |
7369 __ bind(&no_info); | 7369 __ bind(&no_info); |
7370 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 7370 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
7371 } | 7371 } |
7372 | 7372 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7457 __ bind(&fast_elements_case); | 7457 __ bind(&fast_elements_case); |
7458 GenerateCase(masm, FAST_ELEMENTS); | 7458 GenerateCase(masm, FAST_ELEMENTS); |
7459 } | 7459 } |
7460 | 7460 |
7461 | 7461 |
7462 #undef __ | 7462 #undef __ |
7463 | 7463 |
7464 } } // namespace v8::internal | 7464 } } // namespace v8::internal |
7465 | 7465 |
7466 #endif // V8_TARGET_ARCH_IA32 | 7466 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |