| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 void ToNumberStub::InitializeInterfaceDescriptor( | 57 void ToNumberStub::InitializeInterfaceDescriptor( |
| 58 Isolate* isolate, | 58 Isolate* isolate, |
| 59 CodeStubInterfaceDescriptor* descriptor) { | 59 CodeStubInterfaceDescriptor* descriptor) { |
| 60 static Register registers[] = { eax }; | 60 static Register registers[] = { eax }; |
| 61 descriptor->register_param_count_ = 1; | 61 descriptor->register_param_count_ = 1; |
| 62 descriptor->register_params_ = registers; | 62 descriptor->register_params_ = registers; |
| 63 descriptor->deoptimization_handler_ = NULL; | 63 descriptor->deoptimization_handler_ = NULL; |
| 64 } | 64 } |
| 65 | 65 |
| 66 | 66 |
| 67 void NumberToStringStub::InitializeInterfaceDescriptor( |
| 68 Isolate* isolate, |
| 69 CodeStubInterfaceDescriptor* descriptor) { |
| 70 static Register registers[] = { eax }; |
| 71 descriptor->register_param_count_ = 1; |
| 72 descriptor->register_params_ = registers; |
| 73 descriptor->deoptimization_handler_ = NULL; |
| 74 } |
| 75 |
| 76 |
| 67 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( | 77 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( |
| 68 Isolate* isolate, | 78 Isolate* isolate, |
| 69 CodeStubInterfaceDescriptor* descriptor) { | 79 CodeStubInterfaceDescriptor* descriptor) { |
| 70 static Register registers[] = { eax, ebx, ecx }; | 80 static Register registers[] = { eax, ebx, ecx }; |
| 71 descriptor->register_param_count_ = 3; | 81 descriptor->register_param_count_ = 3; |
| 72 descriptor->register_params_ = registers; | 82 descriptor->register_params_ = registers; |
| 73 descriptor->deoptimization_handler_ = | 83 descriptor->deoptimization_handler_ = |
| 74 Runtime::FunctionForId(Runtime::kCreateArrayLiteralShallow)->entry; | 84 Runtime::FunctionForId(Runtime::kCreateArrayLiteralShallow)->entry; |
| 75 } | 85 } |
| 76 | 86 |
| (...skipping 3683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3760 __ jmp(&loop); | 3770 __ jmp(&loop); |
| 3761 | 3771 |
| 3762 __ bind(&done); | 3772 __ bind(&done); |
| 3763 __ ret(3 * kPointerSize); | 3773 __ ret(3 * kPointerSize); |
| 3764 | 3774 |
| 3765 __ bind(&slowcase); | 3775 __ bind(&slowcase); |
| 3766 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); | 3776 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); |
| 3767 } | 3777 } |
| 3768 | 3778 |
| 3769 | 3779 |
| 3770 void NumberToStringStub::Generate(MacroAssembler* masm) { | |
| 3771 Label runtime; | |
| 3772 | |
| 3773 __ mov(ebx, Operand(esp, kPointerSize)); | |
| 3774 | |
| 3775 // Generate code to lookup number in the number string cache. | |
| 3776 __ LookupNumberStringCache(ebx, eax, ecx, edx, &runtime); | |
| 3777 __ ret(1 * kPointerSize); | |
| 3778 | |
| 3779 __ bind(&runtime); | |
| 3780 // Handle number to string in the runtime system if not found in the cache. | |
| 3781 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); | |
| 3782 } | |
| 3783 | |
| 3784 | |
| 3785 static int NegativeComparisonResult(Condition cc) { | 3780 static int NegativeComparisonResult(Condition cc) { |
| 3786 ASSERT(cc != equal); | 3781 ASSERT(cc != equal); |
| 3787 ASSERT((cc == less) || (cc == less_equal) | 3782 ASSERT((cc == less) || (cc == less_equal) |
| 3788 || (cc == greater) || (cc == greater_equal)); | 3783 || (cc == greater) || (cc == greater_equal)); |
| 3789 return (cc == greater || cc == greater_equal) ? LESS : GREATER; | 3784 return (cc == greater || cc == greater_equal) ? LESS : GREATER; |
| 3790 } | 3785 } |
| 3791 | 3786 |
| 3792 | 3787 |
| 3793 static void CheckInputType(MacroAssembler* masm, | 3788 static void CheckInputType(MacroAssembler* masm, |
| 3794 Register input, | 3789 Register input, |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4112 | 4107 |
| 4113 __ bind(&miss); | 4108 __ bind(&miss); |
| 4114 GenerateMiss(masm); | 4109 GenerateMiss(masm); |
| 4115 } | 4110 } |
| 4116 | 4111 |
| 4117 | 4112 |
| 4118 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 4113 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
| 4119 // Cache the called function in a global property cell. Cache states | 4114 // Cache the called function in a global property cell. Cache states |
| 4120 // are uninitialized, monomorphic (indicated by a JSFunction), and | 4115 // are uninitialized, monomorphic (indicated by a JSFunction), and |
| 4121 // megamorphic. | 4116 // megamorphic. |
| 4117 // eax : number of arguments to the construct function |
| 4122 // ebx : cache cell for call target | 4118 // ebx : cache cell for call target |
| 4123 // edi : the function to call | 4119 // edi : the function to call |
| 4124 Isolate* isolate = masm->isolate(); | 4120 Isolate* isolate = masm->isolate(); |
| 4125 Label initialize, done, miss, megamorphic, not_array_function; | 4121 Label initialize, done, miss, megamorphic, not_array_function; |
| 4126 | 4122 |
| 4127 // Load the cache state into ecx. | 4123 // Load the cache state into ecx. |
| 4128 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset)); | 4124 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset)); |
| 4129 | 4125 |
| 4130 // A monomorphic cache hit or an already megamorphic state: invoke the | 4126 // A monomorphic cache hit or an already megamorphic state: invoke the |
| 4131 // function without changing the state. | 4127 // function without changing the state. |
| 4132 __ cmp(ecx, edi); | 4128 __ cmp(ecx, edi); |
| 4133 __ j(equal, &done); | 4129 __ j(equal, &done); |
| 4134 __ cmp(ecx, Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); | 4130 __ cmp(ecx, Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); |
| 4135 __ j(equal, &done); | 4131 __ j(equal, &done); |
| 4136 | 4132 |
| 4137 // If we came here, we need to see if we are the array function. | 4133 // 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 | 4134 // 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 | 4135 // sentinel, then we have in the cell either some other function or an |
| 4140 // AllocationSite. Do a map check on the object in ecx. | 4136 // AllocationSite. Do a map check on the object in ecx. |
| 4141 Handle<Map> allocation_site_map( | 4137 Handle<Map> allocation_site_map = |
| 4142 masm->isolate()->heap()->allocation_site_map(), | 4138 masm->isolate()->factory()->allocation_site_map(); |
| 4143 masm->isolate()); | |
| 4144 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); | 4139 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); |
| 4145 __ j(not_equal, &miss); | 4140 __ j(not_equal, &miss); |
| 4146 | 4141 |
| 4147 // Load the global or builtins object from the current context | 4142 // Load the global or builtins object from the current context |
| 4148 __ LoadGlobalContext(ecx); | 4143 __ LoadGlobalContext(ecx); |
| 4149 // Make sure the function is the Array() function | 4144 // Make sure the function is the Array() function |
| 4150 __ cmp(edi, Operand(ecx, | 4145 __ cmp(edi, Operand(ecx, |
| 4151 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); | 4146 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); |
| 4152 __ j(not_equal, &megamorphic); | 4147 __ j(not_equal, &megamorphic); |
| 4153 __ jmp(&done); | 4148 __ jmp(&done); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4172 // Make sure the function is the Array() function | 4167 // Make sure the function is the Array() function |
| 4173 __ cmp(edi, Operand(ecx, | 4168 __ cmp(edi, Operand(ecx, |
| 4174 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); | 4169 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); |
| 4175 __ j(not_equal, ¬_array_function); | 4170 __ j(not_equal, ¬_array_function); |
| 4176 | 4171 |
| 4177 // The target function is the Array constructor, | 4172 // The target function is the Array constructor, |
| 4178 // Create an AllocationSite if we don't already have it, store it in the cell | 4173 // Create an AllocationSite if we don't already have it, store it in the cell |
| 4179 { | 4174 { |
| 4180 FrameScope scope(masm, StackFrame::INTERNAL); | 4175 FrameScope scope(masm, StackFrame::INTERNAL); |
| 4181 | 4176 |
| 4177 // Arguments register must be smi-tagged to call out. |
| 4182 __ SmiTag(eax); | 4178 __ SmiTag(eax); |
| 4183 __ push(eax); | 4179 __ push(eax); |
| 4184 __ push(edi); | 4180 __ push(edi); |
| 4185 __ push(ebx); | 4181 __ push(ebx); |
| 4186 | 4182 |
| 4187 CreateAllocationSiteStub create_stub; | 4183 CreateAllocationSiteStub create_stub; |
| 4188 __ CallStub(&create_stub); | 4184 __ CallStub(&create_stub); |
| 4189 | 4185 |
| 4190 __ pop(ebx); | 4186 __ pop(ebx); |
| 4191 __ pop(edi); | 4187 __ pop(edi); |
| (...skipping 3012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7204 ArraySingleArgumentConstructorStub stub(initial, | 7200 ArraySingleArgumentConstructorStub stub(initial, |
| 7205 CONTEXT_CHECK_REQUIRED, | 7201 CONTEXT_CHECK_REQUIRED, |
| 7206 DISABLE_ALLOCATION_SITES); | 7202 DISABLE_ALLOCATION_SITES); |
| 7207 __ TailCallStub(&stub); | 7203 __ TailCallStub(&stub); |
| 7208 } else if (mode == DONT_OVERRIDE) { | 7204 } else if (mode == DONT_OVERRIDE) { |
| 7209 // We are going to create a holey array, but our kind is non-holey. | 7205 // We are going to create a holey array, but our kind is non-holey. |
| 7210 // Fix kind and retry. | 7206 // Fix kind and retry. |
| 7211 __ inc(edx); | 7207 __ inc(edx); |
| 7212 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset)); | 7208 __ mov(ecx, FieldOperand(ebx, Cell::kValueOffset)); |
| 7213 if (FLAG_debug_code) { | 7209 if (FLAG_debug_code) { |
| 7214 Handle<Map> allocation_site_map( | 7210 Handle<Map> allocation_site_map = |
| 7215 masm->isolate()->heap()->allocation_site_map(), | 7211 masm->isolate()->factory()->allocation_site_map(); |
| 7216 masm->isolate()); | |
| 7217 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); | 7212 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); |
| 7218 __ Assert(equal, kExpectedAllocationSiteInCell); | 7213 __ Assert(equal, kExpectedAllocationSiteInCell); |
| 7219 } | 7214 } |
| 7220 | 7215 |
| 7221 // Save the resulting elements kind in type info | 7216 // Save the resulting elements kind in type info |
| 7222 __ SmiTag(edx); | 7217 __ SmiTag(edx); |
| 7223 __ mov(FieldOperand(ecx, AllocationSite::kTransitionInfoOffset), edx); | 7218 __ mov(FieldOperand(ecx, AllocationSite::kTransitionInfoOffset), edx); |
| 7224 __ SmiUntag(edx); | 7219 __ SmiUntag(edx); |
| 7225 | 7220 |
| 7226 __ bind(&normal_sequence); | 7221 __ bind(&normal_sequence); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7351 __ Assert(equal, kExpectedPropertyCellInRegisterEbx); | 7346 __ Assert(equal, kExpectedPropertyCellInRegisterEbx); |
| 7352 __ bind(&okay_here); | 7347 __ bind(&okay_here); |
| 7353 } | 7348 } |
| 7354 | 7349 |
| 7355 Label no_info; | 7350 Label no_info; |
| 7356 // If the type cell is undefined, or contains anything other than an | 7351 // If the type cell is undefined, or contains anything other than an |
| 7357 // AllocationSite, call an array constructor that doesn't use AllocationSites. | 7352 // AllocationSite, call an array constructor that doesn't use AllocationSites. |
| 7358 __ cmp(ebx, Immediate(undefined_sentinel)); | 7353 __ cmp(ebx, Immediate(undefined_sentinel)); |
| 7359 __ j(equal, &no_info); | 7354 __ j(equal, &no_info); |
| 7360 __ mov(edx, FieldOperand(ebx, Cell::kValueOffset)); | 7355 __ mov(edx, FieldOperand(ebx, Cell::kValueOffset)); |
| 7361 __ cmp(FieldOperand(edx, 0), Immediate(Handle<Map>( | 7356 __ cmp(FieldOperand(edx, 0), Immediate( |
| 7362 masm->isolate()->heap()->allocation_site_map()))); | 7357 masm->isolate()->factory()->allocation_site_map())); |
| 7363 __ j(not_equal, &no_info); | 7358 __ j(not_equal, &no_info); |
| 7364 | 7359 |
| 7365 __ mov(edx, FieldOperand(edx, AllocationSite::kTransitionInfoOffset)); | 7360 __ mov(edx, FieldOperand(edx, AllocationSite::kTransitionInfoOffset)); |
| 7366 __ SmiUntag(edx); | 7361 __ SmiUntag(edx); |
| 7367 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 7362 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
| 7368 | 7363 |
| 7369 __ bind(&no_info); | 7364 __ bind(&no_info); |
| 7370 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 7365 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
| 7371 } | 7366 } |
| 7372 | 7367 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7457 __ bind(&fast_elements_case); | 7452 __ bind(&fast_elements_case); |
| 7458 GenerateCase(masm, FAST_ELEMENTS); | 7453 GenerateCase(masm, FAST_ELEMENTS); |
| 7459 } | 7454 } |
| 7460 | 7455 |
| 7461 | 7456 |
| 7462 #undef __ | 7457 #undef __ |
| 7463 | 7458 |
| 7464 } } // namespace v8::internal | 7459 } } // namespace v8::internal |
| 7465 | 7460 |
| 7466 #endif // V8_TARGET_ARCH_IA32 | 7461 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |