blob: e89cb4b9d6e787e8239ca75caac4b8818c164cc2 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005#include "src/ic/ic-compiler.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006
7#include "src/ic/handler-compiler.h"
8#include "src/ic/ic-inl.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009#include "src/profiler/cpu-profiler.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010
11
12namespace v8 {
13namespace internal {
14
15
Emily Bernierd0a1eb72015-03-24 16:35:39 -040016Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000017 Handle<Map> receiver_map, ExtraICState extra_ic_state) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040018 Isolate* isolate = receiver_map->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000020 ElementsKind elements_kind = receiver_map->elements_kind();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000021
22 // No need to check for an elements-free prototype chain here, the generated
23 // stub code needs to check that dynamically anyway.
24 bool convert_hole_to_undefined =
25 is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
Ben Murdoch097c5b22016-05-18 11:27:45 +010026 *receiver_map == isolate->get_initial_js_array_map(elements_kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000027 Handle<Code> stub;
28 if (receiver_map->has_indexed_interceptor()) {
Ben Murdochc5610432016-08-08 18:44:38 +010029 TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadIndexedInterceptorStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030 stub = LoadIndexedInterceptorStub(isolate).GetCode();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040031 } else if (receiver_map->IsStringMap()) {
Ben Murdochc5610432016-08-08 18:44:38 +010032 TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadIndexedStringStub);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040033 stub = LoadIndexedStringStub(isolate).GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034 } else if (receiver_map->has_sloppy_arguments_elements()) {
Ben Murdochc5610432016-08-08 18:44:38 +010035 TRACE_HANDLER_STATS(isolate, KeyedLoadIC_KeyedLoadSloppyArgumentsStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036 stub = KeyedLoadSloppyArgumentsStub(isolate).GetCode();
37 } else if (receiver_map->has_fast_elements() ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +000038 receiver_map->has_fixed_typed_array_elements()) {
Ben Murdochc5610432016-08-08 18:44:38 +010039 TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadFastElementStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 stub = LoadFastElementStub(isolate, is_js_array, elements_kind,
41 convert_hole_to_undefined).GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000042 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +010043 DCHECK(receiver_map->has_dictionary_elements());
Ben Murdochc5610432016-08-08 18:44:38 +010044 TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadDictionaryElementStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000045 stub = LoadDictionaryElementStub(isolate, LoadICState(extra_ic_state))
46 .GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040048 return stub;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000049}
50
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
Ben Murdochc5610432016-08-08 18:44:38 +010052 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000053 Isolate* isolate = receiver_map->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054
55 DCHECK(store_mode == STANDARD_STORE ||
56 store_mode == STORE_AND_GROW_NO_TRANSITION ||
57 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
58 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
59
Ben Murdochc5610432016-08-08 18:44:38 +010060 PropertyICCompiler compiler(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 Handle<Code> code =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062 compiler.CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063 return code;
64}
65
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000066void PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
67 MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
Ben Murdochc5610432016-08-08 18:44:38 +010068 CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 Isolate* isolate = receiver_maps->at(0)->GetIsolate();
70 DCHECK(store_mode == STANDARD_STORE ||
71 store_mode == STORE_AND_GROW_NO_TRANSITION ||
72 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
73 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
Ben Murdochc5610432016-08-08 18:44:38 +010074 PropertyICCompiler compiler(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075 compiler.CompileKeyedStorePolymorphicHandlers(
76 receiver_maps, transitioned_maps, handlers, store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000077}
78
79
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers(
81 MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
82 CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000083 for (int i = 0; i < receiver_maps->length(); ++i) {
84 Handle<Map> receiver_map(receiver_maps->at(i));
85 Handle<Code> cached_stub;
Ben Murdochc5610432016-08-08 18:44:38 +010086 Handle<Map> transitioned_map;
87 {
88 Map* tmap = receiver_map->FindElementsKindTransitionedMap(receiver_maps);
89 if (tmap != nullptr) transitioned_map = handle(tmap);
90 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091
92 // TODO(mvstanton): The code below is doing pessimistic elements
93 // transitions. I would like to stop doing that and rely on Allocation Site
94 // Tracking to do a better job of ensuring the data types are what they need
95 // to be. Not all the elements are in place yet, pessimistic elements
96 // transitions are still important for performance.
97 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
98 ElementsKind elements_kind = receiver_map->elements_kind();
99 if (!transitioned_map.is_null()) {
100 cached_stub =
101 ElementsTransitionAndStoreStub(isolate(), elements_kind,
102 transitioned_map->elements_kind(),
103 is_js_array, store_mode).GetCode();
104 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 // TODO(mvstanton): Consider embedding store_mode in the state of the slow
106 // keyed store ic for uniformity.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000107 cached_stub = isolate()->builtins()->KeyedStoreIC_Slow();
108 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000109 if (IsSloppyArgumentsElements(elements_kind)) {
110 cached_stub =
111 KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode();
112 } else if (receiver_map->has_fast_elements() ||
113 receiver_map->has_fixed_typed_array_elements()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000114 cached_stub = StoreFastElementStub(isolate(), is_js_array,
115 elements_kind, store_mode).GetCode();
116 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000117 cached_stub =
118 StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000119 }
120 }
121 DCHECK(!cached_stub.is_null());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000122 handlers->Add(cached_stub);
123 transitioned_maps->Add(transitioned_map);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000124 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000125}
126
127
128#define __ ACCESS_MASM(masm())
129
130
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000131Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphicHandler(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
133 ElementsKind elements_kind = receiver_map->elements_kind();
134 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
135 Handle<Code> stub;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000136 if (receiver_map->has_sloppy_arguments_elements()) {
Ben Murdochc5610432016-08-08 18:44:38 +0100137 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_KeyedStoreSloppyArgumentsStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000138 stub = KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode();
139 } else if (receiver_map->has_fast_elements() ||
140 receiver_map->has_fixed_typed_array_elements()) {
Ben Murdochc5610432016-08-08 18:44:38 +0100141 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000142 stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
143 store_mode).GetCode();
144 } else {
Ben Murdochc5610432016-08-08 18:44:38 +0100145 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000146 stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000148 return stub;
149}
150
151
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000152#undef __
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000153} // namespace internal
154} // namespace v8