blob: af025fbafd0c71f69e8c5a0000c8b8c97894e187 [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 Murdochb8a8cc12014-11-26 15:28:44 +00009
10namespace v8 {
11namespace internal {
12
13
Emily Bernierd0a1eb72015-03-24 16:35:39 -040014Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015 Handle<Map> receiver_map, ExtraICState extra_ic_state) {
Ben Murdoch61f157c2016-09-16 13:49:30 +010016 // TODO(ishell): remove extra_ic_state
Emily Bernierd0a1eb72015-03-24 16:35:39 -040017 Isolate* isolate = receiver_map->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000018 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019 ElementsKind elements_kind = receiver_map->elements_kind();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020
21 // No need to check for an elements-free prototype chain here, the generated
22 // stub code needs to check that dynamically anyway.
23 bool convert_hole_to_undefined =
24 is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
Ben Murdoch097c5b22016-05-18 11:27:45 +010025 *receiver_map == isolate->get_initial_js_array_map(elements_kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000026 Handle<Code> stub;
27 if (receiver_map->has_indexed_interceptor()) {
Ben Murdochc5610432016-08-08 18:44:38 +010028 TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadIndexedInterceptorStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029 stub = LoadIndexedInterceptorStub(isolate).GetCode();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040030 } else if (receiver_map->IsStringMap()) {
Ben Murdochc5610432016-08-08 18:44:38 +010031 TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadIndexedStringStub);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040032 stub = LoadIndexedStringStub(isolate).GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033 } else if (receiver_map->has_sloppy_arguments_elements()) {
Ben Murdochc5610432016-08-08 18:44:38 +010034 TRACE_HANDLER_STATS(isolate, KeyedLoadIC_KeyedLoadSloppyArgumentsStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035 stub = KeyedLoadSloppyArgumentsStub(isolate).GetCode();
36 } else if (receiver_map->has_fast_elements() ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +000037 receiver_map->has_fixed_typed_array_elements()) {
Ben Murdochc5610432016-08-08 18:44:38 +010038 TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadFastElementStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039 stub = LoadFastElementStub(isolate, is_js_array, elements_kind,
40 convert_hole_to_undefined).GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +010042 DCHECK(receiver_map->has_dictionary_elements());
Ben Murdochc5610432016-08-08 18:44:38 +010043 TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadDictionaryElementStub);
Ben Murdoch61f157c2016-09-16 13:49:30 +010044 stub = LoadDictionaryElementStub(isolate).GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040046 return stub;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047}
48
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000049Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
Ben Murdochc5610432016-08-08 18:44:38 +010050 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051 Isolate* isolate = receiver_map->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000052
53 DCHECK(store_mode == STANDARD_STORE ||
54 store_mode == STORE_AND_GROW_NO_TRANSITION ||
55 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
56 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
57
Ben Murdochc5610432016-08-08 18:44:38 +010058 PropertyICCompiler compiler(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059 Handle<Code> code =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060 compiler.CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 return code;
62}
63
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064void PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
65 MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
Ben Murdochc5610432016-08-08 18:44:38 +010066 CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000067 Isolate* isolate = receiver_maps->at(0)->GetIsolate();
68 DCHECK(store_mode == STANDARD_STORE ||
69 store_mode == STORE_AND_GROW_NO_TRANSITION ||
70 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
71 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
Ben Murdochc5610432016-08-08 18:44:38 +010072 PropertyICCompiler compiler(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073 compiler.CompileKeyedStorePolymorphicHandlers(
74 receiver_maps, transitioned_maps, handlers, store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075}
76
77
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000078void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers(
79 MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
80 CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 for (int i = 0; i < receiver_maps->length(); ++i) {
82 Handle<Map> receiver_map(receiver_maps->at(i));
83 Handle<Code> cached_stub;
Ben Murdochc5610432016-08-08 18:44:38 +010084 Handle<Map> transitioned_map;
85 {
86 Map* tmap = receiver_map->FindElementsKindTransitionedMap(receiver_maps);
87 if (tmap != nullptr) transitioned_map = handle(tmap);
88 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000089
90 // TODO(mvstanton): The code below is doing pessimistic elements
91 // transitions. I would like to stop doing that and rely on Allocation Site
92 // Tracking to do a better job of ensuring the data types are what they need
93 // to be. Not all the elements are in place yet, pessimistic elements
94 // transitions are still important for performance.
95 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
96 ElementsKind elements_kind = receiver_map->elements_kind();
97 if (!transitioned_map.is_null()) {
98 cached_stub =
99 ElementsTransitionAndStoreStub(isolate(), elements_kind,
100 transitioned_map->elements_kind(),
101 is_js_array, store_mode).GetCode();
102 } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000103 // TODO(mvstanton): Consider embedding store_mode in the state of the slow
104 // keyed store ic for uniformity.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105 cached_stub = isolate()->builtins()->KeyedStoreIC_Slow();
106 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107 if (IsSloppyArgumentsElements(elements_kind)) {
108 cached_stub =
109 KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode();
110 } else if (receiver_map->has_fast_elements() ||
111 receiver_map->has_fixed_typed_array_elements()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112 cached_stub = StoreFastElementStub(isolate(), is_js_array,
113 elements_kind, store_mode).GetCode();
114 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000115 cached_stub =
116 StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000117 }
118 }
119 DCHECK(!cached_stub.is_null());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120 handlers->Add(cached_stub);
121 transitioned_maps->Add(transitioned_map);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000122 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123}
124
125
126#define __ ACCESS_MASM(masm())
127
128
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000129Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphicHandler(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000130 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
131 ElementsKind elements_kind = receiver_map->elements_kind();
132 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
133 Handle<Code> stub;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134 if (receiver_map->has_sloppy_arguments_elements()) {
Ben Murdochc5610432016-08-08 18:44:38 +0100135 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_KeyedStoreSloppyArgumentsStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000136 stub = KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode();
137 } else if (receiver_map->has_fast_elements() ||
138 receiver_map->has_fixed_typed_array_elements()) {
Ben Murdochc5610432016-08-08 18:44:38 +0100139 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140 stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
141 store_mode).GetCode();
142 } else {
Ben Murdochc5610432016-08-08 18:44:38 +0100143 TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000144 stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000146 return stub;
147}
148
149
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150#undef __
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000151} // namespace internal
152} // namespace v8