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 2018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2029 | 2029 |
2030 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( | 2030 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
2031 HValue* checked_object, | 2031 HValue* checked_object, |
2032 HValue* key, | 2032 HValue* key, |
2033 HValue* val, | 2033 HValue* val, |
2034 bool is_js_array, | 2034 bool is_js_array, |
2035 ElementsKind elements_kind, | 2035 ElementsKind elements_kind, |
2036 bool is_store, | 2036 bool is_store, |
2037 LoadKeyedHoleMode load_mode, | 2037 LoadKeyedHoleMode load_mode, |
2038 KeyedAccessStoreMode store_mode) { | 2038 KeyedAccessStoreMode store_mode) { |
2039 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); | 2039 ASSERT((!IsExternalArrayElementsKind(elements_kind) |
2040 && !IsFixedTypedArrayElementsKind(elements_kind)) | |
Toon Verwaest
2013/12/23 10:40:32
&& on previous line. Align new line 1 space furthe
Dmitry Lomov (no reviews)
2014/01/07 15:48:43
Done.
| |
2041 || !is_js_array); | |
2040 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency | 2042 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
2041 // on a HElementsTransition instruction. The flag can also be removed if the | 2043 // on a HElementsTransition instruction. The flag can also be removed if the |
2042 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further | 2044 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
2043 // ElementsKind transitions. Finally, the dependency can be removed for stores | 2045 // ElementsKind transitions. Finally, the dependency can be removed for stores |
2044 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the | 2046 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
2045 // generated store code. | 2047 // generated store code. |
2046 if ((elements_kind == FAST_HOLEY_ELEMENTS) || | 2048 if ((elements_kind == FAST_HOLEY_ELEMENTS) || |
2047 (elements_kind == FAST_ELEMENTS && is_store)) { | 2049 (elements_kind == FAST_ELEMENTS && is_store)) { |
2048 checked_object->ClearGVNFlag(kDependsOnElementsKind); | 2050 checked_object->ClearGVNFlag(kDependsOnElementsKind); |
2049 } | 2051 } |
2050 | 2052 |
2051 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); | 2053 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); |
2052 bool fast_elements = IsFastObjectElementsKind(elements_kind); | 2054 bool fast_elements = IsFastObjectElementsKind(elements_kind); |
2053 HValue* elements = AddLoadElements(checked_object); | 2055 HValue* elements = AddLoadElements(checked_object); |
2054 if (is_store && (fast_elements || fast_smi_only_elements) && | 2056 if (is_store && (fast_elements || fast_smi_only_elements) && |
2055 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { | 2057 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { |
2056 HCheckMaps* check_cow_map = Add<HCheckMaps>( | 2058 HCheckMaps* check_cow_map = Add<HCheckMaps>( |
2057 elements, isolate()->factory()->fixed_array_map(), top_info()); | 2059 elements, isolate()->factory()->fixed_array_map(), top_info()); |
2058 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 2060 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
2059 } | 2061 } |
2060 HInstruction* length = NULL; | 2062 HInstruction* length = NULL; |
2061 if (is_js_array) { | 2063 if (is_js_array) { |
2062 length = Add<HLoadNamedField>( | 2064 length = Add<HLoadNamedField>( |
2063 checked_object, HObjectAccess::ForArrayLength(elements_kind)); | 2065 checked_object, HObjectAccess::ForArrayLength(elements_kind)); |
2064 } else { | 2066 } else { |
2065 length = AddLoadFixedArrayLength(elements); | 2067 length = AddLoadFixedArrayLength(elements); |
2066 } | 2068 } |
2067 length->set_type(HType::Smi()); | 2069 length->set_type(HType::Smi()); |
2068 HValue* checked_key = NULL; | 2070 HValue* checked_key = NULL; |
2069 if (IsExternalArrayElementsKind(elements_kind)) { | 2071 if (IsExternalArrayElementsKind(elements_kind) || |
2072 IsFixedTypedArrayElementsKind(elements_kind)) { | |
2073 HValue* backing_store; | |
2074 if (IsExternalArrayElementsKind(elements_kind)) { | |
2075 backing_store = | |
2076 Add<HLoadExternalArrayPointer>(elements); | |
2077 } else { | |
2078 backing_store = elements; | |
2079 } | |
2070 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 2080 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
2071 NoObservableSideEffectsScope no_effects(this); | 2081 NoObservableSideEffectsScope no_effects(this); |
2072 HLoadExternalArrayPointer* external_elements = | |
2073 Add<HLoadExternalArrayPointer>(elements); | |
2074 IfBuilder length_checker(this); | 2082 IfBuilder length_checker(this); |
2075 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); | 2083 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
2076 length_checker.Then(); | 2084 length_checker.Then(); |
2077 IfBuilder negative_checker(this); | 2085 IfBuilder negative_checker(this); |
2078 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( | 2086 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
2079 key, graph()->GetConstant0(), Token::GTE); | 2087 key, graph()->GetConstant0(), Token::GTE); |
2080 negative_checker.Then(); | 2088 negative_checker.Then(); |
2081 HInstruction* result = AddElementAccess( | 2089 HInstruction* result = AddElementAccess( |
2082 external_elements, key, val, bounds_check, elements_kind, is_store); | 2090 backing_store, key, val, bounds_check, elements_kind, is_store); |
2083 negative_checker.ElseDeopt("Negative key encountered"); | 2091 negative_checker.ElseDeopt("Negative key encountered"); |
2084 negative_checker.End(); | 2092 negative_checker.End(); |
2085 length_checker.End(); | 2093 length_checker.End(); |
2086 return result; | 2094 return result; |
2087 } else { | 2095 } else { |
2088 ASSERT(store_mode == STANDARD_STORE); | 2096 ASSERT(store_mode == STANDARD_STORE); |
2089 checked_key = Add<HBoundsCheck>(key, length); | 2097 checked_key = Add<HBoundsCheck>(key, length); |
2090 HLoadExternalArrayPointer* external_elements = | |
2091 Add<HLoadExternalArrayPointer>(elements); | |
2092 return AddElementAccess( | 2098 return AddElementAccess( |
2093 external_elements, checked_key, val, | 2099 backing_store, checked_key, val, |
2094 checked_object, elements_kind, is_store); | 2100 checked_object, elements_kind, is_store); |
2095 } | 2101 } |
2096 } | 2102 } |
2097 ASSERT(fast_smi_only_elements || | 2103 ASSERT(fast_smi_only_elements || |
2098 fast_elements || | 2104 fast_elements || |
2099 IsFastDoubleElementsKind(elements_kind)); | 2105 IsFastDoubleElementsKind(elements_kind)); |
2100 | 2106 |
2101 // In case val is stored into a fast smi array, assure that the value is a smi | 2107 // In case val is stored into a fast smi array, assure that the value is a smi |
2102 // before manipulating the backing store. Otherwise the actual store may | 2108 // before manipulating the backing store. Otherwise the actual store may |
2103 // deopt, leaving the backing store in an invalid state. | 2109 // deopt, leaving the backing store in an invalid state. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2264 HInstruction* HGraphBuilder::AddElementAccess( | 2270 HInstruction* HGraphBuilder::AddElementAccess( |
2265 HValue* elements, | 2271 HValue* elements, |
2266 HValue* checked_key, | 2272 HValue* checked_key, |
2267 HValue* val, | 2273 HValue* val, |
2268 HValue* dependency, | 2274 HValue* dependency, |
2269 ElementsKind elements_kind, | 2275 ElementsKind elements_kind, |
2270 bool is_store, | 2276 bool is_store, |
2271 LoadKeyedHoleMode load_mode) { | 2277 LoadKeyedHoleMode load_mode) { |
2272 if (is_store) { | 2278 if (is_store) { |
2273 ASSERT(val != NULL); | 2279 ASSERT(val != NULL); |
2274 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { | 2280 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS || |
2281 elements_kind == UINT8_CLAMPED_ELEMENTS) { | |
2275 val = Add<HClampToUint8>(val); | 2282 val = Add<HClampToUint8>(val); |
2276 } | 2283 } |
2277 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, | 2284 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, |
2278 elements_kind == FAST_SMI_ELEMENTS | 2285 elements_kind == FAST_SMI_ELEMENTS |
2279 ? STORE_TO_INITIALIZED_ENTRY | 2286 ? STORE_TO_INITIALIZED_ENTRY |
2280 : INITIALIZING_STORE); | 2287 : INITIALIZING_STORE); |
2281 } | 2288 } |
2282 | 2289 |
2283 ASSERT(!is_store); | 2290 ASSERT(!is_store); |
2284 ASSERT(val == NULL); | 2291 ASSERT(val == NULL); |
2285 HLoadKeyed* load = Add<HLoadKeyed>( | 2292 HLoadKeyed* load = Add<HLoadKeyed>( |
2286 elements, checked_key, dependency, elements_kind, load_mode); | 2293 elements, checked_key, dependency, elements_kind, load_mode); |
2287 if (FLAG_opt_safe_uint32_operations && | 2294 if (FLAG_opt_safe_uint32_operations && |
2288 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 2295 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS || |
2296 elements_kind == UINT32_ELEMENTS)) { | |
2289 graph()->RecordUint32Instruction(load); | 2297 graph()->RecordUint32Instruction(load); |
2290 } | 2298 } |
2291 return load; | 2299 return load; |
2292 } | 2300 } |
2293 | 2301 |
2294 | 2302 |
2295 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) { | 2303 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) { |
2296 return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer()); | 2304 return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer()); |
2297 } | 2305 } |
2298 | 2306 |
(...skipping 8493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10792 if (ShouldProduceTraceOutput()) { | 10800 if (ShouldProduceTraceOutput()) { |
10793 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10801 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10794 } | 10802 } |
10795 | 10803 |
10796 #ifdef DEBUG | 10804 #ifdef DEBUG |
10797 graph_->Verify(false); // No full verify. | 10805 graph_->Verify(false); // No full verify. |
10798 #endif | 10806 #endif |
10799 } | 10807 } |
10800 | 10808 |
10801 } } // namespace v8::internal | 10809 } } // namespace v8::internal |
OLD | NEW |