Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: src/ic/handler-compiler.cc

Issue 2623483002: [cleanup] Port KeyedLoadIC_{Slow,Miss} to TF and drop unused IC handler code (Closed)
Patch Set: rebased Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ic/handler-compiler.h ('k') | src/ic/ia32/handler-compiler-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/handler-compiler.h" 5 #include "src/ic/handler-compiler.h"
6 6
7 #include "src/field-type.h" 7 #include "src/field-type.h"
8 #include "src/ic/call-optimization.h" 8 #include "src/ic/call-optimization.h"
9 #include "src/ic/handler-configuration-inl.h" 9 #include "src/ic/handler-configuration-inl.h"
10 #include "src/ic/ic-inl.h" 10 #include "src/ic/ic-inl.h"
11 #include "src/ic/ic.h" 11 #include "src/ic/ic.h"
12 #include "src/isolate-inl.h" 12 #include "src/isolate-inl.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name, 17 Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name,
18 Handle<Map> stub_holder, 18 Handle<Map> stub_holder,
19 Code::Kind kind, 19 Code::Kind kind,
20 CacheHolderFlag cache_holder) { 20 CacheHolderFlag cache_holder) {
21 Code::Flags flags = Code::ComputeHandlerFlags(kind, cache_holder); 21 Code::Flags flags = Code::ComputeHandlerFlags(kind, cache_holder);
22 Code* code = stub_holder->LookupInCodeCache(*name, flags); 22 Code* code = stub_holder->LookupInCodeCache(*name, flags);
23 if (code == nullptr) return Handle<Code>(); 23 if (code == nullptr) return Handle<Code>();
24 return handle(code); 24 return handle(code);
25 } 25 }
26 26
27
28 Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
29 Handle<Name> name, Handle<Map> receiver_map) {
30 Isolate* isolate = name->GetIsolate();
31 if (receiver_map->prototype()->IsNull(isolate)) {
32 // TODO(jkummerow/verwaest): If there is no prototype and the property
33 // is nonexistent, introduce a builtin to handle this (fast properties
34 // -> return undefined, dictionary properties -> do negative lookup).
35 return Handle<Code>();
36 }
37 CacheHolderFlag flag;
38 Handle<Map> stub_holder_map =
39 IC::GetHandlerCacheHolder(receiver_map, false, isolate, &flag);
40
41 // If no dictionary mode objects are present in the prototype chain, the load
42 // nonexistent IC stub can be shared for all names for a given map and we use
43 // the empty string for the map cache in that case. If there are dictionary
44 // mode objects involved, we need to do negative lookups in the stub and
45 // therefore the stub will be specific to the name.
46 Handle<Name> cache_name =
47 receiver_map->is_dictionary_map()
48 ? name
49 : Handle<Name>::cast(isolate->factory()->nonexistent_symbol());
50 Handle<Map> current_map = stub_holder_map;
51 Handle<JSObject> last(JSObject::cast(receiver_map->prototype()));
52 while (true) {
53 if (current_map->is_dictionary_map()) cache_name = name;
54 if (current_map->prototype()->IsNull(isolate)) break;
55 if (name->IsPrivate()) {
56 // TODO(verwaest): Use nonexistent_private_symbol.
57 cache_name = name;
58 if (!current_map->has_hidden_prototype()) break;
59 }
60
61 last = handle(JSObject::cast(current_map->prototype()));
62 current_map = handle(last->map());
63 }
64 // Compile the stub that is either shared for all names or
65 // name specific if there are global objects involved.
66 Handle<Code> handler = PropertyHandlerCompiler::Find(
67 cache_name, stub_holder_map, Code::LOAD_IC, flag);
68 if (!handler.is_null()) {
69 TRACE_HANDLER_STATS(isolate, LoadIC_HandlerCacheHit_NonExistent);
70 return handler;
71 }
72
73 TRACE_HANDLER_STATS(isolate, LoadIC_LoadNonexistent);
74 NamedLoadHandlerCompiler compiler(isolate, receiver_map, last, flag);
75 handler = compiler.CompileLoadNonexistent(cache_name);
76 Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
77 return handler;
78 }
79
80
81 Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind, 27 Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind,
82 Handle<Name> name) { 28 Handle<Name> name) {
83 Code::Flags flags = Code::ComputeHandlerFlags(kind, cache_holder()); 29 Code::Flags flags = Code::ComputeHandlerFlags(kind, cache_holder());
84 Handle<Code> code = GetCodeWithFlags(flags, name); 30 Handle<Code> code = GetCodeWithFlags(flags, name);
85 PROFILE(isolate(), CodeCreateEvent(CodeEventListener::HANDLER_TAG, 31 PROFILE(isolate(), CodeCreateEvent(CodeEventListener::HANDLER_TAG,
86 AbstractCode::cast(*code), *name)); 32 AbstractCode::cast(*code), *name));
87 #ifdef DEBUG 33 #ifdef DEBUG
88 code->VerifyEmbeddedObjects(); 34 code->VerifyEmbeddedObjects();
89 #endif 35 #endif
90 return code; 36 return code;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 } 88 }
143 Register reg = FrontendHeader(receiver(), name, &miss, RETURN_HOLDER); 89 Register reg = FrontendHeader(receiver(), name, &miss, RETURN_HOLDER);
144 FrontendFooter(name, &miss); 90 FrontendFooter(name, &miss);
145 // The footer consumes the vector and slot from the stack if miss occurs. 91 // The footer consumes the vector and slot from the stack if miss occurs.
146 if (IC::ShouldPushPopSlotAndVector(kind())) { 92 if (IC::ShouldPushPopSlotAndVector(kind())) {
147 DiscardVectorAndSlot(); 93 DiscardVectorAndSlot();
148 } 94 }
149 return reg; 95 return reg;
150 } 96 }
151 97
152
153 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name,
154 Label* miss,
155 Register scratch1,
156 Register scratch2) {
157 Register holder_reg;
158 Handle<Map> last_map;
159 if (holder().is_null()) {
160 holder_reg = receiver();
161 last_map = map();
162 // If |type| has null as its prototype, |holder()| is
163 // Handle<JSObject>::null().
164 DCHECK(last_map->prototype()->IsNull(isolate()));
165 } else {
166 last_map = handle(holder()->map());
167 // This condition matches the branches below.
168 bool need_holder =
169 last_map->is_dictionary_map() && !last_map->IsJSGlobalObjectMap();
170 holder_reg =
171 FrontendHeader(receiver(), name, miss,
172 need_holder ? RETURN_HOLDER : DONT_RETURN_ANYTHING);
173 }
174
175 if (last_map->is_dictionary_map()) {
176 if (last_map->IsJSGlobalObjectMap()) {
177 Handle<JSGlobalObject> global =
178 holder().is_null()
179 ? Handle<JSGlobalObject>::cast(isolate()->global_object())
180 : Handle<JSGlobalObject>::cast(holder());
181 GenerateCheckPropertyCell(masm(), global, name, scratch1, miss);
182 } else {
183 if (!name->IsUniqueName()) {
184 DCHECK(name->IsString());
185 name = factory()->InternalizeString(Handle<String>::cast(name));
186 }
187 DCHECK(holder().is_null() ||
188 holder()->property_dictionary()->FindEntry(name) ==
189 NameDictionary::kNotFound);
190 GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1,
191 scratch2);
192 }
193 }
194 }
195
196 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
197 Handle<Name> name) {
198 Label miss;
199 if (IC::ShouldPushPopSlotAndVector(kind())) {
200 DCHECK(kind() == Code::LOAD_IC);
201 PushVectorAndSlot();
202 }
203 NonexistentFrontendHeader(name, &miss, scratch2(), scratch3());
204 if (IC::ShouldPushPopSlotAndVector(kind())) {
205 DiscardVectorAndSlot();
206 }
207 GenerateLoadConstant(isolate()->factory()->undefined_value());
208 FrontendFooter(name, &miss);
209 return GetCode(kind(), name);
210 }
211
212 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 98 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
213 Handle<Name> name, Handle<AccessorInfo> callback, Handle<Code> slow_stub) { 99 Handle<Name> name, Handle<AccessorInfo> callback, Handle<Code> slow_stub) {
214 if (V8_UNLIKELY(FLAG_runtime_stats)) { 100 if (V8_UNLIKELY(FLAG_runtime_stats)) {
215 GenerateTailCall(masm(), slow_stub); 101 GenerateTailCall(masm(), slow_stub);
216 } 102 }
217 Register reg = Frontend(name); 103 Register reg = Frontend(name);
218 GenerateLoadCallback(reg, callback); 104 GenerateLoadCallback(reg, callback);
219 return GetCode(kind(), name); 105 return GetCode(kind(), name);
220 } 106 }
221 107
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 } 301 }
416 302
417 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter( 303 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
418 Handle<Name> name, int accessor_index, int expected_arguments) { 304 Handle<Name> name, int accessor_index, int expected_arguments) {
419 Register holder = Frontend(name); 305 Register holder = Frontend(name);
420 GenerateLoadViaGetter(masm(), map(), receiver(), holder, accessor_index, 306 GenerateLoadViaGetter(masm(), map(), receiver(), holder, accessor_index,
421 expected_arguments, scratch2()); 307 expected_arguments, scratch2());
422 return GetCode(kind(), name); 308 return GetCode(kind(), name);
423 } 309 }
424 310
425 bool NamedStoreHandlerCompiler::RequiresFieldTypeChecks(
426 FieldType* field_type) const {
427 return field_type->IsClass();
428 }
429
430 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter( 311 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
431 Handle<JSObject> object, Handle<Name> name, int accessor_index, 312 Handle<JSObject> object, Handle<Name> name, int accessor_index,
432 int expected_arguments) { 313 int expected_arguments) {
433 Register holder = Frontend(name); 314 Register holder = Frontend(name);
434 GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index, 315 GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index,
435 expected_arguments, scratch2()); 316 expected_arguments, scratch2());
436 317
437 return GetCode(kind(), name); 318 return GetCode(kind(), name);
438 } 319 }
439 320
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 } 379 }
499 380
500 void ElementHandlerCompiler::CompileElementHandlers( 381 void ElementHandlerCompiler::CompileElementHandlers(
501 MapHandleList* receiver_maps, List<Handle<Object>>* handlers) { 382 MapHandleList* receiver_maps, List<Handle<Object>>* handlers) {
502 for (int i = 0; i < receiver_maps->length(); ++i) { 383 for (int i = 0; i < receiver_maps->length(); ++i) {
503 handlers->Add(GetKeyedLoadHandler(receiver_maps->at(i), isolate())); 384 handlers->Add(GetKeyedLoadHandler(receiver_maps->at(i), isolate()));
504 } 385 }
505 } 386 }
506 } // namespace internal 387 } // namespace internal
507 } // namespace v8 388 } // namespace v8
OLDNEW
« no previous file with comments | « src/ic/handler-compiler.h ('k') | src/ic/ia32/handler-compiler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698