Chromium Code Reviews| 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 |