| 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 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2129 elements, isolate()->factory()->fixed_array_map(), top_info()); | 2129 elements, isolate()->factory()->fixed_array_map(), top_info()); |
| 2130 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 2130 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
| 2131 } | 2131 } |
| 2132 } | 2132 } |
| 2133 } | 2133 } |
| 2134 return AddElementAccess(elements, checked_key, val, checked_object, | 2134 return AddElementAccess(elements, checked_key, val, checked_object, |
| 2135 elements_kind, is_store, load_mode); | 2135 elements_kind, is_store, load_mode); |
| 2136 } | 2136 } |
| 2137 | 2137 |
| 2138 | 2138 |
| 2139 | |
| 2140 HValue* HGraphBuilder::BuildAllocateArrayFromLength( | 2139 HValue* HGraphBuilder::BuildAllocateArrayFromLength( |
| 2141 JSArrayBuilder* array_builder, | 2140 JSArrayBuilder* array_builder, |
| 2142 HValue* length_argument) { | 2141 HValue* length_argument) { |
| 2143 if (length_argument->IsConstant() && | 2142 if (length_argument->IsConstant() && |
| 2144 HConstant::cast(length_argument)->HasSmiValue()) { | 2143 HConstant::cast(length_argument)->HasSmiValue()) { |
| 2145 int array_length = HConstant::cast(length_argument)->Integer32Value(); | 2144 int array_length = HConstant::cast(length_argument)->Integer32Value(); |
| 2146 HValue* new_object = array_length == 0 | 2145 HValue* new_object = array_length == 0 |
| 2147 ? array_builder->AllocateEmptyArray() | 2146 ? array_builder->AllocateEmptyArray() |
| 2148 : array_builder->AllocateArray(length_argument, length_argument); | 2147 : array_builder->AllocateArray(length_argument, length_argument); |
| 2149 return new_object; | 2148 return new_object; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2172 Push(checked_length); // length | 2171 Push(checked_length); // length |
| 2173 } | 2172 } |
| 2174 if_builder.End(); | 2173 if_builder.End(); |
| 2175 | 2174 |
| 2176 // Figure out total size | 2175 // Figure out total size |
| 2177 HValue* length = Pop(); | 2176 HValue* length = Pop(); |
| 2178 HValue* capacity = Pop(); | 2177 HValue* capacity = Pop(); |
| 2179 return array_builder->AllocateArray(capacity, length); | 2178 return array_builder->AllocateArray(capacity, length); |
| 2180 } | 2179 } |
| 2181 | 2180 |
| 2182 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, | 2181 HValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind, |
| 2183 HValue* capacity) { | 2182 HValue* capacity) { |
| 2184 int elements_size; | 2183 int elements_size = IsFastDoubleElementsKind(kind) |
| 2185 InstanceType instance_type; | 2184 ? kDoubleSize |
| 2186 | 2185 : kPointerSize; |
| 2187 if (IsFastDoubleElementsKind(kind)) { | |
| 2188 elements_size = kDoubleSize; | |
| 2189 instance_type = FIXED_DOUBLE_ARRAY_TYPE; | |
| 2190 } else { | |
| 2191 elements_size = kPointerSize; | |
| 2192 instance_type = FIXED_ARRAY_TYPE; | |
| 2193 } | |
| 2194 | 2186 |
| 2195 HConstant* elements_size_value = Add<HConstant>(elements_size); | 2187 HConstant* elements_size_value = Add<HConstant>(elements_size); |
| 2196 HValue* mul = AddUncasted<HMul>(capacity, elements_size_value); | 2188 HInstruction* mul = HMul::NewImul(zone(), context(), |
| 2189 capacity->ActualValue(), |
| 2190 elements_size_value); |
| 2191 AddInstruction(mul); |
| 2197 mul->ClearFlag(HValue::kCanOverflow); | 2192 mul->ClearFlag(HValue::kCanOverflow); |
| 2198 | 2193 |
| 2194 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); |
| 2195 |
| 2199 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); | 2196 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); |
| 2200 HValue* total_size = AddUncasted<HAdd>(mul, header_size); | 2197 HValue* total_size = AddUncasted<HAdd>(mul, header_size); |
| 2201 total_size->ClearFlag(HValue::kCanOverflow); | 2198 total_size->ClearFlag(HValue::kCanOverflow); |
| 2199 return total_size; |
| 2200 } |
| 2202 | 2201 |
| 2203 return Add<HAllocate>(total_size, HType::JSArray(), | 2202 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, |
| 2204 isolate()->heap()->GetPretenureMode(), instance_type); | 2203 HValue* size_in_bytes, |
| 2204 PretenureFlag pretenure) { |
| 2205 InstanceType instance_type = IsFastDoubleElementsKind(kind) |
| 2206 ? FIXED_DOUBLE_ARRAY_TYPE |
| 2207 : FIXED_ARRAY_TYPE; |
| 2208 |
| 2209 return Add<HAllocate>(size_in_bytes, HType::JSArray(), |
| 2210 pretenure, instance_type); |
| 2205 } | 2211 } |
| 2206 | 2212 |
| 2207 | 2213 |
| 2208 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, | 2214 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, |
| 2209 ElementsKind kind, | 2215 ElementsKind kind, |
| 2210 HValue* capacity) { | 2216 HValue* capacity) { |
| 2211 Factory* factory = isolate()->factory(); | 2217 Factory* factory = isolate()->factory(); |
| 2212 Handle<Map> map = IsFastDoubleElementsKind(kind) | 2218 Handle<Map> map = IsFastDoubleElementsKind(kind) |
| 2213 ? factory->fixed_double_array_map() | 2219 ? factory->fixed_double_array_map() |
| 2214 : factory->fixed_array_map(); | 2220 : factory->fixed_array_map(); |
| 2215 | 2221 |
| 2216 AddStoreMapConstant(elements, map); | 2222 AddStoreMapConstant(elements, map); |
| 2217 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), | 2223 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), |
| 2218 capacity); | 2224 capacity); |
| 2219 } | 2225 } |
| 2220 | 2226 |
| 2221 | 2227 |
| 2222 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( | 2228 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( |
| 2223 ElementsKind kind, | 2229 ElementsKind kind, |
| 2224 HValue* capacity) { | 2230 HValue* capacity) { |
| 2225 // The HForceRepresentation is to prevent possible deopt on int-smi | 2231 // The HForceRepresentation is to prevent possible deopt on int-smi |
| 2226 // conversion after allocation but before the new object fields are set. | 2232 // conversion after allocation but before the new object fields are set. |
| 2227 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); | 2233 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); |
| 2228 HValue* new_elements = BuildAllocateElements(kind, capacity); | 2234 HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity); |
| 2235 HValue* new_elements = BuildAllocateElements( |
| 2236 kind, size_in_bytes, isolate()->heap()->GetPretenureMode()); |
| 2229 BuildInitializeElementsHeader(new_elements, kind, capacity); | 2237 BuildInitializeElementsHeader(new_elements, kind, capacity); |
| 2230 return new_elements; | 2238 return new_elements; |
| 2231 } | 2239 } |
| 2232 | 2240 |
| 2233 | 2241 |
| 2234 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, | 2242 void HGraphBuilder::BuildJSArrayHeader(HValue* array, |
| 2235 HValue* array_map, | 2243 HValue* array_map, |
| 2236 AllocationSiteMode mode, | 2244 AllocationSiteMode mode, |
| 2237 ElementsKind elements_kind, | 2245 ElementsKind elements_kind, |
| 2238 HValue* allocation_site_payload, | 2246 HValue* allocation_site_payload, |
| 2239 HValue* length_field) { | 2247 HValue* length_field) { |
| 2240 | |
| 2241 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); | 2248 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map); |
| 2242 | 2249 |
| 2243 HConstant* empty_fixed_array = | 2250 HConstant* empty_fixed_array = |
| 2244 Add<HConstant>(isolate()->factory()->empty_fixed_array()); | 2251 Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
| 2245 | 2252 |
| 2246 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); | 2253 Add<HStoreNamedField>( |
| 2247 Add<HStoreNamedField>(array, access, empty_fixed_array); | 2254 array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array); |
| 2248 Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind), | 2255 |
| 2249 length_field); | 2256 Add<HStoreNamedField>( |
| 2257 array, HObjectAccess::ForElementsPointer(), empty_fixed_array); |
| 2258 |
| 2259 Add<HStoreNamedField>( |
| 2260 array, HObjectAccess::ForArrayLength(elements_kind), length_field); |
| 2250 | 2261 |
| 2251 if (mode == TRACK_ALLOCATION_SITE) { | 2262 if (mode == TRACK_ALLOCATION_SITE) { |
| 2252 BuildCreateAllocationMemento(array, | 2263 BuildCreateAllocationMemento(array, |
| 2253 JSArray::kSize, | 2264 JSArray::kSize, |
| 2254 allocation_site_payload); | 2265 allocation_site_payload); |
| 2255 } | 2266 } |
| 2256 | |
| 2257 int elements_location = JSArray::kSize; | |
| 2258 if (mode == TRACK_ALLOCATION_SITE) { | |
| 2259 elements_location += AllocationMemento::kSize; | |
| 2260 } | |
| 2261 | |
| 2262 HValue* elements = Add<HInnerAllocatedObject>(array, elements_location); | |
| 2263 Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements); | |
| 2264 return static_cast<HInnerAllocatedObject*>(elements); | |
| 2265 } | 2267 } |
| 2266 | 2268 |
| 2267 | 2269 |
| 2268 HInstruction* HGraphBuilder::AddElementAccess( | 2270 HInstruction* HGraphBuilder::AddElementAccess( |
| 2269 HValue* elements, | 2271 HValue* elements, |
| 2270 HValue* checked_key, | 2272 HValue* checked_key, |
| 2271 HValue* val, | 2273 HValue* val, |
| 2272 HValue* dependency, | 2274 HValue* dependency, |
| 2273 ElementsKind elements_kind, | 2275 ElementsKind elements_kind, |
| 2274 bool is_store, | 2276 bool is_store, |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2672 } | 2674 } |
| 2673 | 2675 |
| 2674 | 2676 |
| 2675 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 2677 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
| 2676 // Find the map near the constructor function | 2678 // Find the map near the constructor function |
| 2677 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 2679 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 2678 return builder()->AddLoadNamedField(constructor_function_, access); | 2680 return builder()->AddLoadNamedField(constructor_function_, access); |
| 2679 } | 2681 } |
| 2680 | 2682 |
| 2681 | 2683 |
| 2682 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 2684 HValue* HGraphBuilder::JSArrayBuilder::EstablishHeaderAllocationSize() { |
| 2683 HValue* length_node) { | |
| 2684 ASSERT(length_node != NULL); | |
| 2685 | |
| 2686 int base_size = JSArray::kSize; | 2685 int base_size = JSArray::kSize; |
| 2687 if (mode_ == TRACK_ALLOCATION_SITE) { | 2686 if (mode_ == TRACK_ALLOCATION_SITE) { |
| 2688 base_size += AllocationMemento::kSize; | 2687 base_size += AllocationMemento::kSize; |
| 2689 } | 2688 } |
| 2690 | |
| 2691 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); | |
| 2692 base_size += FixedArray::kHeaderSize; | |
| 2693 | |
| 2694 HInstruction* elements_size_value = | |
| 2695 builder()->Add<HConstant>(elements_size()); | |
| 2696 HInstruction* mul = HMul::NewImul(builder()->zone(), builder()->context(), | |
| 2697 length_node, elements_size_value); | |
| 2698 builder()->AddInstruction(mul); | |
| 2699 HInstruction* base = builder()->Add<HConstant>(base_size); | |
| 2700 HInstruction* total_size = HAdd::New(builder()->zone(), builder()->context(), | |
| 2701 base, mul); | |
| 2702 total_size->ClearFlag(HValue::kCanOverflow); | |
| 2703 builder()->AddInstruction(total_size); | |
| 2704 return total_size; | |
| 2705 } | |
| 2706 | |
| 2707 | |
| 2708 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { | |
| 2709 int base_size = JSArray::kSize; | |
| 2710 if (mode_ == TRACK_ALLOCATION_SITE) { | |
| 2711 base_size += AllocationMemento::kSize; | |
| 2712 } | |
| 2713 | |
| 2714 base_size += IsFastDoubleElementsKind(kind_) | |
| 2715 ? FixedDoubleArray::SizeFor(initial_capacity()) | |
| 2716 : FixedArray::SizeFor(initial_capacity()); | |
| 2717 | |
| 2718 return builder()->Add<HConstant>(base_size); | 2689 return builder()->Add<HConstant>(base_size); |
| 2719 } | 2690 } |
| 2720 | 2691 |
| 2721 | 2692 |
| 2722 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { | 2693 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { |
| 2723 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); | |
| 2724 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); | 2694 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); |
| 2725 return AllocateArray(size_in_bytes, | 2695 return AllocateArray(capacity, |
| 2726 capacity, | |
| 2727 builder()->graph()->GetConstant0()); | 2696 builder()->graph()->GetConstant0()); |
| 2728 } | 2697 } |
| 2729 | 2698 |
| 2730 | 2699 |
| 2731 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, | 2700 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, |
| 2732 HValue* length_field, | 2701 HValue* length_field, |
| 2733 FillMode fill_mode) { | 2702 FillMode fill_mode) { |
| 2734 HValue* size_in_bytes = EstablishAllocationSize(capacity); | |
| 2735 return AllocateArray(size_in_bytes, capacity, length_field, fill_mode); | |
| 2736 } | |
| 2737 | |
| 2738 | |
| 2739 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, | |
| 2740 HValue* capacity, | |
| 2741 HValue* length_field, | |
| 2742 FillMode fill_mode) { | |
| 2743 // These HForceRepresentations are because we store these as fields in the | 2703 // These HForceRepresentations are because we store these as fields in the |
| 2744 // objects we construct, and an int32-to-smi HChange could deopt. Accept | 2704 // objects we construct, and an int32-to-smi HChange could deopt. Accept |
| 2745 // the deopt possibility now, before allocation occurs. | 2705 // the deopt possibility now, before allocation occurs. |
| 2746 capacity = | 2706 capacity = |
| 2747 builder()->AddUncasted<HForceRepresentation>(capacity, | 2707 builder()->AddUncasted<HForceRepresentation>(capacity, |
| 2748 Representation::Smi()); | 2708 Representation::Smi()); |
| 2749 length_field = | 2709 length_field = |
| 2750 builder()->AddUncasted<HForceRepresentation>(length_field, | 2710 builder()->AddUncasted<HForceRepresentation>(length_field, |
| 2751 Representation::Smi()); | 2711 Representation::Smi()); |
| 2712 |
| 2713 // Generate size calculation code here in order to make it dominate |
| 2714 // the JSArray allocation. |
| 2715 HValue* elms_size = builder()->BuildCalculateElementsSize(kind_, capacity); |
| 2716 |
| 2752 // Allocate (dealing with failure appropriately) | 2717 // Allocate (dealing with failure appropriately) |
| 2753 HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes, | 2718 HValue* array_object_size = EstablishHeaderAllocationSize(); |
| 2719 HAllocate* array_object = builder()->Add<HAllocate>(array_object_size, |
| 2754 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); | 2720 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); |
| 2755 | 2721 |
| 2756 // Folded array allocation should be aligned if it has fast double elements. | |
| 2757 if (IsFastDoubleElementsKind(kind_)) { | |
| 2758 new_object->MakeDoubleAligned(); | |
| 2759 } | |
| 2760 | |
| 2761 // Fill in the fields: map, properties, length | 2722 // Fill in the fields: map, properties, length |
| 2762 HValue* map; | 2723 HValue* map; |
| 2763 if (allocation_site_payload_ == NULL) { | 2724 if (allocation_site_payload_ == NULL) { |
| 2764 map = EmitInternalMapCode(); | 2725 map = EmitInternalMapCode(); |
| 2765 } else { | 2726 } else { |
| 2766 map = EmitMapCode(); | 2727 map = EmitMapCode(); |
| 2767 } | 2728 } |
| 2768 elements_location_ = builder()->BuildJSArrayHeader(new_object, | |
| 2769 map, | |
| 2770 mode_, | |
| 2771 kind_, | |
| 2772 allocation_site_payload_, | |
| 2773 length_field); | |
| 2774 | 2729 |
| 2775 // Initialize the elements | 2730 builder()->BuildJSArrayHeader(array_object, |
| 2731 map, |
| 2732 mode_, |
| 2733 kind_, |
| 2734 allocation_site_payload_, |
| 2735 length_field); |
| 2736 |
| 2737 // Allocate and initialize the elements |
| 2738 elements_location_ = |
| 2739 builder()->BuildAllocateElements(kind_, elms_size, NOT_TENURED); |
| 2740 |
| 2776 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); | 2741 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); |
| 2777 | 2742 |
| 2743 // Set the elements |
| 2744 builder()->Add<HStoreNamedField>( |
| 2745 array_object, HObjectAccess::ForElementsPointer(), elements_location_); |
| 2746 |
| 2778 if (fill_mode == FILL_WITH_HOLE) { | 2747 if (fill_mode == FILL_WITH_HOLE) { |
| 2779 builder()->BuildFillElementsWithHole(elements_location_, kind_, | 2748 builder()->BuildFillElementsWithHole(elements_location_, kind_, |
| 2780 graph()->GetConstant0(), capacity); | 2749 graph()->GetConstant0(), capacity); |
| 2781 } | 2750 } |
| 2782 | 2751 |
| 2783 return new_object; | 2752 return array_object; |
| 2784 } | 2753 } |
| 2785 | 2754 |
| 2786 | 2755 |
| 2787 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, | 2756 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, |
| 2788 Handle<Map> map) { | 2757 Handle<Map> map) { |
| 2789 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), | 2758 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), |
| 2790 Add<HConstant>(map)); | 2759 Add<HConstant>(map)); |
| 2791 } | 2760 } |
| 2792 | 2761 |
| 2793 | 2762 |
| (...skipping 7876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10670 if (ShouldProduceTraceOutput()) { | 10639 if (ShouldProduceTraceOutput()) { |
| 10671 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10640 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 10672 } | 10641 } |
| 10673 | 10642 |
| 10674 #ifdef DEBUG | 10643 #ifdef DEBUG |
| 10675 graph_->Verify(false); // No full verify. | 10644 graph_->Verify(false); // No full verify. |
| 10676 #endif | 10645 #endif |
| 10677 } | 10646 } |
| 10678 | 10647 |
| 10679 } } // namespace v8::internal | 10648 } } // namespace v8::internal |
| OLD | NEW |