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 |