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