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

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

Issue 908213002: Use Cells to check prototype chain validity (disabled by default). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix arm64 typo (and rebase, sorry) Created 5 years, 8 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/cpu-profiler.h" 7 #include "src/cpu-profiler.h"
8 #include "src/ic/call-optimization.h" 8 #include "src/ic/call-optimization.h"
9 #include "src/ic/handler-compiler.h" 9 #include "src/ic/handler-compiler.h"
10 #include "src/ic/ic.h" 10 #include "src/ic/ic.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 #endif 80 #endif
81 return code; 81 return code;
82 } 82 }
83 83
84 84
85 #define __ ACCESS_MASM(masm()) 85 #define __ ACCESS_MASM(masm())
86 86
87 87
88 Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg, 88 Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
89 Handle<Name> name, 89 Handle<Name> name,
90 Label* miss) { 90 Label* miss,
91 ReturnHolder return_what) {
91 PrototypeCheckType check_type = CHECK_ALL_MAPS; 92 PrototypeCheckType check_type = CHECK_ALL_MAPS;
92 int function_index = -1; 93 int function_index = -1;
93 if (map()->instance_type() < FIRST_NONSTRING_TYPE) { 94 if (map()->instance_type() < FIRST_NONSTRING_TYPE) {
94 function_index = Context::STRING_FUNCTION_INDEX; 95 function_index = Context::STRING_FUNCTION_INDEX;
95 } else if (map()->instance_type() == SYMBOL_TYPE) { 96 } else if (map()->instance_type() == SYMBOL_TYPE) {
96 function_index = Context::SYMBOL_FUNCTION_INDEX; 97 function_index = Context::SYMBOL_FUNCTION_INDEX;
97 } else if (map()->instance_type() == HEAP_NUMBER_TYPE) { 98 } else if (map()->instance_type() == HEAP_NUMBER_TYPE) {
98 function_index = Context::NUMBER_FUNCTION_INDEX; 99 function_index = Context::NUMBER_FUNCTION_INDEX;
99 } else if (*map() == isolate()->heap()->boolean_map()) { 100 } else if (*map() == isolate()->heap()->boolean_map()) {
100 function_index = Context::BOOLEAN_FUNCTION_INDEX; 101 function_index = Context::BOOLEAN_FUNCTION_INDEX;
101 } else { 102 } else {
102 check_type = SKIP_RECEIVER; 103 check_type = SKIP_RECEIVER;
103 } 104 }
104 105
105 if (check_type == CHECK_ALL_MAPS) { 106 if (check_type == CHECK_ALL_MAPS) {
106 GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index, 107 GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index,
107 scratch1(), miss); 108 scratch1(), miss);
108 Object* function = isolate()->native_context()->get(function_index); 109 Object* function = isolate()->native_context()->get(function_index);
109 Object* prototype = JSFunction::cast(function)->instance_prototype(); 110 Object* prototype = JSFunction::cast(function)->instance_prototype();
110 Handle<Map> map(JSObject::cast(prototype)->map()); 111 Handle<Map> map(JSObject::cast(prototype)->map());
111 set_map(map); 112 set_map(map);
112 object_reg = scratch1(); 113 object_reg = scratch1();
113 } 114 }
114 115
115 // Check that the maps starting from the prototype haven't changed. 116 // Check that the maps starting from the prototype haven't changed.
116 return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name, 117 return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name,
117 miss, check_type); 118 miss, check_type, return_what);
118 } 119 }
119 120
120 121
121 // Frontend for store uses the name register. It has to be restored before a 122 // Frontend for store uses the name register. It has to be restored before a
122 // miss. 123 // miss.
123 Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg, 124 Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg,
124 Handle<Name> name, 125 Handle<Name> name,
125 Label* miss) { 126 Label* miss,
127 ReturnHolder return_what) {
126 return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name, 128 return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name,
127 miss, SKIP_RECEIVER); 129 miss, SKIP_RECEIVER, return_what);
128 } 130 }
129 131
130 132
131 Register PropertyHandlerCompiler::Frontend(Handle<Name> name) { 133 Register PropertyHandlerCompiler::Frontend(Handle<Name> name) {
132 Label miss; 134 Label miss;
133 if (IC::ICUseVector(kind())) { 135 if (IC::ICUseVector(kind())) {
134 PushVectorAndSlot(); 136 PushVectorAndSlot();
135 } 137 }
136 Register reg = FrontendHeader(receiver(), name, &miss); 138 Register reg = FrontendHeader(receiver(), name, &miss, RETURN_HOLDER);
137 FrontendFooter(name, &miss); 139 FrontendFooter(name, &miss);
138 // The footer consumes the vector and slot from the stack if miss occurs. 140 // The footer consumes the vector and slot from the stack if miss occurs.
139 if (IC::ICUseVector(kind())) { 141 if (IC::ICUseVector(kind())) {
140 DiscardVectorAndSlot(); 142 DiscardVectorAndSlot();
141 } 143 }
142 return reg; 144 return reg;
143 } 145 }
144 146
145 147
146 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name, 148 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name,
147 Label* miss, 149 Label* miss,
148 Register scratch1, 150 Register scratch1,
149 Register scratch2) { 151 Register scratch2) {
150 Register holder_reg; 152 Register holder_reg;
151 Handle<Map> last_map; 153 Handle<Map> last_map;
152 if (holder().is_null()) { 154 if (holder().is_null()) {
153 holder_reg = receiver(); 155 holder_reg = receiver();
154 last_map = map(); 156 last_map = map();
155 // If |type| has null as its prototype, |holder()| is 157 // If |type| has null as its prototype, |holder()| is
156 // Handle<JSObject>::null(). 158 // Handle<JSObject>::null().
157 DCHECK(last_map->prototype() == isolate()->heap()->null_value()); 159 DCHECK(last_map->prototype() == isolate()->heap()->null_value());
158 } else { 160 } else {
159 holder_reg = FrontendHeader(receiver(), name, miss);
160 last_map = handle(holder()->map()); 161 last_map = handle(holder()->map());
162 // This condition matches the branches below.
163 bool need_holder =
164 last_map->is_dictionary_map() && !last_map->IsJSGlobalObjectMap();
165 holder_reg =
166 FrontendHeader(receiver(), name, miss,
167 need_holder ? RETURN_HOLDER : DONT_RETURN_ANYTHING);
161 } 168 }
162 169
163 if (last_map->is_dictionary_map()) { 170 if (last_map->is_dictionary_map()) {
164 if (last_map->IsJSGlobalObjectMap()) { 171 if (last_map->IsJSGlobalObjectMap()) {
165 Handle<JSGlobalObject> global = 172 Handle<JSGlobalObject> global =
166 holder().is_null() 173 holder().is_null()
167 ? Handle<JSGlobalObject>::cast(isolate()->global_object()) 174 ? Handle<JSGlobalObject>::cast(isolate()->global_object())
168 : Handle<JSGlobalObject>::cast(holder()); 175 : Handle<JSGlobalObject>::cast(holder());
169 GenerateCheckPropertyCell(masm(), global, name, scratch1, miss); 176 GenerateCheckPropertyCell(masm(), global, name, scratch1, miss);
170 } else { 177 } else {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 JSObject* last = *holder(); 328 JSObject* last = *holder();
322 PrototypeIterator iter(isolate(), last); 329 PrototypeIterator iter(isolate(), last);
323 while (!iter.IsAtEnd()) { 330 while (!iter.IsAtEnd()) {
324 lost_holder_register = true; 331 lost_holder_register = true;
325 last = JSObject::cast(iter.GetCurrent()); 332 last = JSObject::cast(iter.GetCurrent());
326 iter.Advance(); 333 iter.Advance();
327 } 334 }
328 auto last_handle = handle(last); 335 auto last_handle = handle(last);
329 set_holder(last_handle); 336 set_holder(last_handle);
330 } 337 }
331 Register reg = FrontendHeader(receiver(), it->name(), &miss); 338 Register reg = FrontendHeader(receiver(), it->name(), &miss, RETURN_HOLDER);
332 // Reset the holder so further calculations are correct. 339 // Reset the holder so further calculations are correct.
333 set_holder(holder_orig); 340 set_holder(holder_orig);
334 if (lost_holder_register) { 341 if (lost_holder_register) {
335 if (*it->GetReceiver() == *holder()) { 342 if (*it->GetReceiver() == *holder()) {
336 reg = receiver(); 343 reg = receiver();
337 } else { 344 } else {
338 // Reload lost holder register. 345 // Reload lost holder register.
339 auto cell = isolate()->factory()->NewWeakCell(holder()); 346 auto cell = isolate()->factory()->NewWeakCell(holder());
340 __ LoadWeakValue(reg, cell, &miss); 347 __ LoadWeakValue(reg, cell, &miss);
341 } 348 }
(...skipping 14 matching lines...) Expand all
356 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( 363 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
357 LookupIterator* it, Register interceptor_reg) { 364 LookupIterator* it, Register interceptor_reg) {
358 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>()); 365 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>());
359 366
360 Handle<Map> holder_map(holder()->map()); 367 Handle<Map> holder_map(holder()->map());
361 set_map(holder_map); 368 set_map(holder_map);
362 set_holder(real_named_property_holder); 369 set_holder(real_named_property_holder);
363 370
364 Label miss; 371 Label miss;
365 InterceptorVectorSlotPush(interceptor_reg); 372 InterceptorVectorSlotPush(interceptor_reg);
366 Register reg = FrontendHeader(interceptor_reg, it->name(), &miss); 373 Register reg =
374 FrontendHeader(interceptor_reg, it->name(), &miss, RETURN_HOLDER);
367 FrontendFooter(it->name(), &miss); 375 FrontendFooter(it->name(), &miss);
368 // We discard the vector and slot now because we don't miss below this point. 376 // We discard the vector and slot now because we don't miss below this point.
369 InterceptorVectorSlotPop(reg, DISCARD); 377 InterceptorVectorSlotPop(reg, DISCARD);
370 378
371 switch (it->state()) { 379 switch (it->state()) {
372 case LookupIterator::ACCESS_CHECK: 380 case LookupIterator::ACCESS_CHECK:
373 case LookupIterator::INTERCEPTOR: 381 case LookupIterator::INTERCEPTOR:
374 case LookupIterator::JSPROXY: 382 case LookupIterator::JSPROXY:
375 case LookupIterator::NOT_FOUND: 383 case LookupIterator::NOT_FOUND:
376 case LookupIterator::INTEGER_INDEXED_EXOTIC: 384 case LookupIterator::INTEGER_INDEXED_EXOTIC:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 // Find the top object. 429 // Find the top object.
422 Handle<JSObject> last; 430 Handle<JSObject> last;
423 PrototypeIterator iter(isolate(), holder()); 431 PrototypeIterator iter(isolate(), holder());
424 while (!iter.IsAtEnd()) { 432 while (!iter.IsAtEnd()) {
425 last = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 433 last = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
426 iter.Advance(); 434 iter.Advance();
427 } 435 }
428 if (!last.is_null()) set_holder(last); 436 if (!last.is_null()) set_holder(last);
429 NonexistentFrontendHeader(name, &miss, scratch1(), scratch2()); 437 NonexistentFrontendHeader(name, &miss, scratch1(), scratch2());
430 } else { 438 } else {
431 FrontendHeader(receiver(), name, &miss); 439 FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING);
432 DCHECK(holder()->HasFastProperties()); 440 DCHECK(holder()->HasFastProperties());
433 } 441 }
434 442
435 int descriptor = transition->LastAdded(); 443 int descriptor = transition->LastAdded();
436 Handle<DescriptorArray> descriptors(transition->instance_descriptors()); 444 Handle<DescriptorArray> descriptors(transition->instance_descriptors());
437 PropertyDetails details = descriptors->GetDetails(descriptor); 445 PropertyDetails details = descriptors->GetDetails(descriptor);
438 Representation representation = details.representation(); 446 Representation representation = details.representation();
439 DCHECK(!representation.IsNone()); 447 DCHECK(!representation.IsNone());
440 448
441 // Stub is never generated for objects that require access checks. 449 // Stub is never generated for objects that require access checks.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 DCHECK(elements_kind == DICTIONARY_ELEMENTS); 549 DCHECK(elements_kind == DICTIONARY_ELEMENTS);
542 cached_stub = LoadDictionaryElementStub(isolate()).GetCode(); 550 cached_stub = LoadDictionaryElementStub(isolate()).GetCode();
543 } 551 }
544 } 552 }
545 553
546 handlers->Add(cached_stub); 554 handlers->Add(cached_stub);
547 } 555 }
548 } 556 }
549 } 557 }
550 } // namespace v8::internal 558 } // namespace v8::internal
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