| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ic/ic-compiler.h" | 5 #include "src/ic/ic-compiler.h" |
| 6 | 6 |
| 7 #include "src/ic/handler-compiler.h" | 7 #include "src/ic/handler-compiler.h" |
| 8 #include "src/ic/ic-inl.h" | 8 #include "src/ic/ic-inl.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| 11 namespace internal { | 11 namespace internal { |
| 12 | 12 |
| 13 Handle<Object> PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( | 13 Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( |
| 14 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) { | 14 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) { |
| 15 Isolate* isolate = receiver_map->GetIsolate(); | 15 Isolate* isolate = receiver_map->GetIsolate(); |
| 16 | 16 |
| 17 DCHECK(store_mode == STANDARD_STORE || | 17 DCHECK(store_mode == STANDARD_STORE || |
| 18 store_mode == STORE_AND_GROW_NO_TRANSITION || | 18 store_mode == STORE_AND_GROW_NO_TRANSITION || |
| 19 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 19 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
| 20 store_mode == STORE_NO_TRANSITION_HANDLE_COW); | 20 store_mode == STORE_NO_TRANSITION_HANDLE_COW); |
| 21 | 21 |
| 22 PropertyICCompiler compiler(isolate); | 22 PropertyICCompiler compiler(isolate); |
| 23 Handle<Object> handler = | 23 Handle<Code> code = |
| 24 compiler.CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode); | 24 compiler.CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode); |
| 25 return handler; | 25 return code; |
| 26 } | 26 } |
| 27 | 27 |
| 28 void PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( | 28 void PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( |
| 29 MapHandleList* receiver_maps, MapHandleList* transitioned_maps, | 29 MapHandleList* receiver_maps, MapHandleList* transitioned_maps, |
| 30 List<Handle<Object>>* handlers, KeyedAccessStoreMode store_mode) { | 30 CodeHandleList* handlers, KeyedAccessStoreMode store_mode) { |
| 31 Isolate* isolate = receiver_maps->at(0)->GetIsolate(); | 31 Isolate* isolate = receiver_maps->at(0)->GetIsolate(); |
| 32 DCHECK(store_mode == STANDARD_STORE || | 32 DCHECK(store_mode == STANDARD_STORE || |
| 33 store_mode == STORE_AND_GROW_NO_TRANSITION || | 33 store_mode == STORE_AND_GROW_NO_TRANSITION || |
| 34 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 34 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
| 35 store_mode == STORE_NO_TRANSITION_HANDLE_COW); | 35 store_mode == STORE_NO_TRANSITION_HANDLE_COW); |
| 36 PropertyICCompiler compiler(isolate); | 36 PropertyICCompiler compiler(isolate); |
| 37 compiler.CompileKeyedStorePolymorphicHandlers( | 37 compiler.CompileKeyedStorePolymorphicHandlers( |
| 38 receiver_maps, transitioned_maps, handlers, store_mode); | 38 receiver_maps, transitioned_maps, handlers, store_mode); |
| 39 } | 39 } |
| 40 | 40 |
| 41 |
| 41 void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers( | 42 void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers( |
| 42 MapHandleList* receiver_maps, MapHandleList* transitioned_maps, | 43 MapHandleList* receiver_maps, MapHandleList* transitioned_maps, |
| 43 List<Handle<Object>>* handlers, KeyedAccessStoreMode store_mode) { | 44 CodeHandleList* handlers, KeyedAccessStoreMode store_mode) { |
| 44 for (int i = 0; i < receiver_maps->length(); ++i) { | 45 for (int i = 0; i < receiver_maps->length(); ++i) { |
| 45 Handle<Map> receiver_map(receiver_maps->at(i)); | 46 Handle<Map> receiver_map(receiver_maps->at(i)); |
| 46 Handle<Object> handler; | 47 Handle<Code> cached_stub; |
| 47 Handle<Map> transitioned_map; | 48 Handle<Map> transitioned_map; |
| 48 { | 49 { |
| 49 Map* tmap = receiver_map->FindElementsKindTransitionedMap(receiver_maps); | 50 Map* tmap = receiver_map->FindElementsKindTransitionedMap(receiver_maps); |
| 50 if (tmap != nullptr) transitioned_map = handle(tmap); | 51 if (tmap != nullptr) transitioned_map = handle(tmap); |
| 51 } | 52 } |
| 52 | 53 |
| 53 // TODO(mvstanton): The code below is doing pessimistic elements | 54 // TODO(mvstanton): The code below is doing pessimistic elements |
| 54 // transitions. I would like to stop doing that and rely on Allocation Site | 55 // transitions. I would like to stop doing that and rely on Allocation Site |
| 55 // Tracking to do a better job of ensuring the data types are what they need | 56 // Tracking to do a better job of ensuring the data types are what they need |
| 56 // to be. Not all the elements are in place yet, pessimistic elements | 57 // to be. Not all the elements are in place yet, pessimistic elements |
| 57 // transitions are still important for performance. | 58 // transitions are still important for performance. |
| 58 if (!transitioned_map.is_null()) { | 59 if (!transitioned_map.is_null()) { |
| 59 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | 60 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; |
| 60 ElementsKind elements_kind = receiver_map->elements_kind(); | 61 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 61 TRACE_HANDLER_STATS(isolate(), | 62 TRACE_HANDLER_STATS(isolate(), |
| 62 KeyedStoreIC_ElementsTransitionAndStoreStub); | 63 KeyedStoreIC_ElementsTransitionAndStoreStub); |
| 63 Handle<Code> stub = | 64 cached_stub = |
| 64 ElementsTransitionAndStoreStub(isolate(), elements_kind, | 65 ElementsTransitionAndStoreStub(isolate(), elements_kind, |
| 65 transitioned_map->elements_kind(), | 66 transitioned_map->elements_kind(), |
| 66 is_js_array, store_mode) | 67 is_js_array, store_mode).GetCode(); |
| 67 .GetCode(); | |
| 68 Handle<Object> validity_cell = | |
| 69 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | |
| 70 handler = isolate()->factory()->NewTuple2(validity_cell, stub); | |
| 71 | |
| 72 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) { | 68 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) { |
| 73 // TODO(mvstanton): Consider embedding store_mode in the state of the slow | 69 // TODO(mvstanton): Consider embedding store_mode in the state of the slow |
| 74 // keyed store ic for uniformity. | 70 // keyed store ic for uniformity. |
| 75 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub); | 71 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub); |
| 76 handler = isolate()->builtins()->KeyedStoreIC_Slow(); | 72 cached_stub = isolate()->builtins()->KeyedStoreIC_Slow(); |
| 77 } else { | 73 } else { |
| 78 handler = CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode); | 74 cached_stub = |
| 75 CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode); |
| 79 } | 76 } |
| 80 DCHECK(!handler.is_null()); | 77 DCHECK(!cached_stub.is_null()); |
| 81 handlers->Add(handler); | 78 handlers->Add(cached_stub); |
| 82 transitioned_maps->Add(transitioned_map); | 79 transitioned_maps->Add(transitioned_map); |
| 83 } | 80 } |
| 84 } | 81 } |
| 85 | 82 |
| 86 | 83 |
| 87 #define __ ACCESS_MASM(masm()) | 84 #define __ ACCESS_MASM(masm()) |
| 88 | 85 |
| 89 Handle<Object> PropertyICCompiler::CompileKeyedStoreMonomorphicHandler( | 86 |
| 87 Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphicHandler( |
| 90 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) { | 88 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) { |
| 91 ElementsKind elements_kind = receiver_map->elements_kind(); | 89 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 92 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; | 90 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; |
| 93 Handle<Code> stub; | 91 Handle<Code> stub; |
| 94 if (receiver_map->has_sloppy_arguments_elements()) { | 92 if (receiver_map->has_sloppy_arguments_elements()) { |
| 95 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_KeyedStoreSloppyArgumentsStub); | 93 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_KeyedStoreSloppyArgumentsStub); |
| 96 stub = KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode(); | 94 stub = KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode(); |
| 97 } else if (receiver_map->has_fast_elements() || | 95 } else if (receiver_map->has_fast_elements() || |
| 98 receiver_map->has_fixed_typed_array_elements()) { | 96 receiver_map->has_fixed_typed_array_elements()) { |
| 99 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub); | 97 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub); |
| 100 stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind, | 98 stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind, |
| 101 store_mode).GetCode(); | 99 store_mode).GetCode(); |
| 102 } else { | 100 } else { |
| 103 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub); | 101 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub); |
| 104 stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode(); | 102 stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode(); |
| 105 } | 103 } |
| 106 Handle<Object> validity_cell = | 104 return stub; |
| 107 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | |
| 108 Handle<Tuple2> handler = isolate()->factory()->NewTuple2(validity_cell, stub); | |
| 109 return handler; | |
| 110 } | 105 } |
| 111 | 106 |
| 112 | 107 |
| 113 #undef __ | 108 #undef __ |
| 114 } // namespace internal | 109 } // namespace internal |
| 115 } // namespace v8 | 110 } // namespace v8 |
| OLD | NEW |