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 2060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2071 | 2071 |
2072 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( | 2072 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
2073 HValue* checked_object, | 2073 HValue* checked_object, |
2074 HValue* key, | 2074 HValue* key, |
2075 HValue* val, | 2075 HValue* val, |
2076 bool is_js_array, | 2076 bool is_js_array, |
2077 ElementsKind elements_kind, | 2077 ElementsKind elements_kind, |
2078 bool is_store, | 2078 bool is_store, |
2079 LoadKeyedHoleMode load_mode, | 2079 LoadKeyedHoleMode load_mode, |
2080 KeyedAccessStoreMode store_mode) { | 2080 KeyedAccessStoreMode store_mode) { |
2081 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); | 2081 ASSERT((!IsExternalArrayElementsKind(elements_kind) && |
| 2082 !IsFixedTypedArrayElementsKind(elements_kind)) || |
| 2083 !is_js_array); |
2082 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency | 2084 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
2083 // on a HElementsTransition instruction. The flag can also be removed if the | 2085 // on a HElementsTransition instruction. The flag can also be removed if the |
2084 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further | 2086 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
2085 // ElementsKind transitions. Finally, the dependency can be removed for stores | 2087 // ElementsKind transitions. Finally, the dependency can be removed for stores |
2086 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the | 2088 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
2087 // generated store code. | 2089 // generated store code. |
2088 if ((elements_kind == FAST_HOLEY_ELEMENTS) || | 2090 if ((elements_kind == FAST_HOLEY_ELEMENTS) || |
2089 (elements_kind == FAST_ELEMENTS && is_store)) { | 2091 (elements_kind == FAST_ELEMENTS && is_store)) { |
2090 checked_object->ClearGVNFlag(kDependsOnElementsKind); | 2092 checked_object->ClearGVNFlag(kDependsOnElementsKind); |
2091 } | 2093 } |
2092 | 2094 |
2093 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); | 2095 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); |
2094 bool fast_elements = IsFastObjectElementsKind(elements_kind); | 2096 bool fast_elements = IsFastObjectElementsKind(elements_kind); |
2095 HValue* elements = AddLoadElements(checked_object); | 2097 HValue* elements = AddLoadElements(checked_object); |
2096 if (is_store && (fast_elements || fast_smi_only_elements) && | 2098 if (is_store && (fast_elements || fast_smi_only_elements) && |
2097 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { | 2099 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { |
2098 HCheckMaps* check_cow_map = Add<HCheckMaps>( | 2100 HCheckMaps* check_cow_map = Add<HCheckMaps>( |
2099 elements, isolate()->factory()->fixed_array_map(), top_info()); | 2101 elements, isolate()->factory()->fixed_array_map(), top_info()); |
2100 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 2102 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
2101 } | 2103 } |
2102 HInstruction* length = NULL; | 2104 HInstruction* length = NULL; |
2103 if (is_js_array) { | 2105 if (is_js_array) { |
2104 length = Add<HLoadNamedField>( | 2106 length = Add<HLoadNamedField>( |
2105 checked_object, HObjectAccess::ForArrayLength(elements_kind)); | 2107 checked_object, HObjectAccess::ForArrayLength(elements_kind)); |
2106 } else { | 2108 } else { |
2107 length = AddLoadFixedArrayLength(elements); | 2109 length = AddLoadFixedArrayLength(elements); |
2108 } | 2110 } |
2109 length->set_type(HType::Smi()); | 2111 length->set_type(HType::Smi()); |
2110 HValue* checked_key = NULL; | 2112 HValue* checked_key = NULL; |
2111 if (IsExternalArrayElementsKind(elements_kind)) { | 2113 if (IsExternalArrayElementsKind(elements_kind) || |
| 2114 IsFixedTypedArrayElementsKind(elements_kind)) { |
| 2115 HValue* backing_store; |
| 2116 if (IsExternalArrayElementsKind(elements_kind)) { |
| 2117 backing_store = |
| 2118 Add<HLoadExternalArrayPointer>(elements); |
| 2119 } else { |
| 2120 backing_store = elements; |
| 2121 } |
2112 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 2122 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
2113 NoObservableSideEffectsScope no_effects(this); | 2123 NoObservableSideEffectsScope no_effects(this); |
2114 HLoadExternalArrayPointer* external_elements = | |
2115 Add<HLoadExternalArrayPointer>(elements); | |
2116 IfBuilder length_checker(this); | 2124 IfBuilder length_checker(this); |
2117 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); | 2125 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
2118 length_checker.Then(); | 2126 length_checker.Then(); |
2119 IfBuilder negative_checker(this); | 2127 IfBuilder negative_checker(this); |
2120 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( | 2128 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
2121 key, graph()->GetConstant0(), Token::GTE); | 2129 key, graph()->GetConstant0(), Token::GTE); |
2122 negative_checker.Then(); | 2130 negative_checker.Then(); |
2123 HInstruction* result = AddElementAccess( | 2131 HInstruction* result = AddElementAccess( |
2124 external_elements, key, val, bounds_check, elements_kind, is_store); | 2132 backing_store, key, val, bounds_check, elements_kind, is_store); |
2125 negative_checker.ElseDeopt("Negative key encountered"); | 2133 negative_checker.ElseDeopt("Negative key encountered"); |
2126 negative_checker.End(); | 2134 negative_checker.End(); |
2127 length_checker.End(); | 2135 length_checker.End(); |
2128 return result; | 2136 return result; |
2129 } else { | 2137 } else { |
2130 ASSERT(store_mode == STANDARD_STORE); | 2138 ASSERT(store_mode == STANDARD_STORE); |
2131 checked_key = Add<HBoundsCheck>(key, length); | 2139 checked_key = Add<HBoundsCheck>(key, length); |
2132 HLoadExternalArrayPointer* external_elements = | |
2133 Add<HLoadExternalArrayPointer>(elements); | |
2134 return AddElementAccess( | 2140 return AddElementAccess( |
2135 external_elements, checked_key, val, | 2141 backing_store, checked_key, val, |
2136 checked_object, elements_kind, is_store); | 2142 checked_object, elements_kind, is_store); |
2137 } | 2143 } |
2138 } | 2144 } |
2139 ASSERT(fast_smi_only_elements || | 2145 ASSERT(fast_smi_only_elements || |
2140 fast_elements || | 2146 fast_elements || |
2141 IsFastDoubleElementsKind(elements_kind)); | 2147 IsFastDoubleElementsKind(elements_kind)); |
2142 | 2148 |
2143 // In case val is stored into a fast smi array, assure that the value is a smi | 2149 // In case val is stored into a fast smi array, assure that the value is a smi |
2144 // before manipulating the backing store. Otherwise the actual store may | 2150 // before manipulating the backing store. Otherwise the actual store may |
2145 // deopt, leaving the backing store in an invalid state. | 2151 // deopt, leaving the backing store in an invalid state. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2306 HInstruction* HGraphBuilder::AddElementAccess( | 2312 HInstruction* HGraphBuilder::AddElementAccess( |
2307 HValue* elements, | 2313 HValue* elements, |
2308 HValue* checked_key, | 2314 HValue* checked_key, |
2309 HValue* val, | 2315 HValue* val, |
2310 HValue* dependency, | 2316 HValue* dependency, |
2311 ElementsKind elements_kind, | 2317 ElementsKind elements_kind, |
2312 bool is_store, | 2318 bool is_store, |
2313 LoadKeyedHoleMode load_mode) { | 2319 LoadKeyedHoleMode load_mode) { |
2314 if (is_store) { | 2320 if (is_store) { |
2315 ASSERT(val != NULL); | 2321 ASSERT(val != NULL); |
2316 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { | 2322 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS || |
| 2323 elements_kind == UINT8_CLAMPED_ELEMENTS) { |
2317 val = Add<HClampToUint8>(val); | 2324 val = Add<HClampToUint8>(val); |
2318 } | 2325 } |
2319 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, | 2326 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, |
2320 elements_kind == FAST_SMI_ELEMENTS | 2327 elements_kind == FAST_SMI_ELEMENTS |
2321 ? STORE_TO_INITIALIZED_ENTRY | 2328 ? STORE_TO_INITIALIZED_ENTRY |
2322 : INITIALIZING_STORE); | 2329 : INITIALIZING_STORE); |
2323 } | 2330 } |
2324 | 2331 |
2325 ASSERT(!is_store); | 2332 ASSERT(!is_store); |
2326 ASSERT(val == NULL); | 2333 ASSERT(val == NULL); |
2327 HLoadKeyed* load = Add<HLoadKeyed>( | 2334 HLoadKeyed* load = Add<HLoadKeyed>( |
2328 elements, checked_key, dependency, elements_kind, load_mode); | 2335 elements, checked_key, dependency, elements_kind, load_mode); |
2329 if (FLAG_opt_safe_uint32_operations && | 2336 if (FLAG_opt_safe_uint32_operations && |
2330 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 2337 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS || |
| 2338 elements_kind == UINT32_ELEMENTS)) { |
2331 graph()->RecordUint32Instruction(load); | 2339 graph()->RecordUint32Instruction(load); |
2332 } | 2340 } |
2333 return load; | 2341 return load; |
2334 } | 2342 } |
2335 | 2343 |
2336 | 2344 |
2337 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) { | 2345 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) { |
2338 return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer()); | 2346 return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer()); |
2339 } | 2347 } |
2340 | 2348 |
(...skipping 8654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10995 if (ShouldProduceTraceOutput()) { | 11003 if (ShouldProduceTraceOutput()) { |
10996 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11004 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10997 } | 11005 } |
10998 | 11006 |
10999 #ifdef DEBUG | 11007 #ifdef DEBUG |
11000 graph_->Verify(false); // No full verify. | 11008 graph_->Verify(false); // No full verify. |
11001 #endif | 11009 #endif |
11002 } | 11010 } |
11003 | 11011 |
11004 } } // namespace v8::internal | 11012 } } // namespace v8::internal |
OLD | NEW |