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

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: rebased onto dropped prototype_object 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
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 // Reload lost holder register. 342 // Reload lost holder register.
336 auto cell = isolate()->factory()->NewWeakCell(holder()); 343 auto cell = isolate()->factory()->NewWeakCell(holder());
337 __ LoadWeakValue(reg, cell, &miss); 344 __ LoadWeakValue(reg, cell, &miss);
338 } 345 }
339 FrontendFooter(it->name(), &miss); 346 FrontendFooter(it->name(), &miss);
340 InterceptorVectorSlotPop(reg); 347 InterceptorVectorSlotPop(reg);
341 if (inline_followup) { 348 if (inline_followup) {
(...skipping 10 matching lines...) Expand all
352 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( 359 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
353 LookupIterator* it, Register interceptor_reg) { 360 LookupIterator* it, Register interceptor_reg) {
354 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>()); 361 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>());
355 362
356 Handle<Map> holder_map(holder()->map()); 363 Handle<Map> holder_map(holder()->map());
357 set_map(holder_map); 364 set_map(holder_map);
358 set_holder(real_named_property_holder); 365 set_holder(real_named_property_holder);
359 366
360 Label miss; 367 Label miss;
361 InterceptorVectorSlotPush(interceptor_reg); 368 InterceptorVectorSlotPush(interceptor_reg);
362 Register reg = FrontendHeader(interceptor_reg, it->name(), &miss); 369 Register reg =
370 FrontendHeader(interceptor_reg, it->name(), &miss, RETURN_HOLDER);
363 FrontendFooter(it->name(), &miss); 371 FrontendFooter(it->name(), &miss);
364 // We discard the vector and slot now because we don't miss below this point. 372 // We discard the vector and slot now because we don't miss below this point.
365 InterceptorVectorSlotPop(reg, DISCARD); 373 InterceptorVectorSlotPop(reg, DISCARD);
366 374
367 switch (it->state()) { 375 switch (it->state()) {
368 case LookupIterator::ACCESS_CHECK: 376 case LookupIterator::ACCESS_CHECK:
369 case LookupIterator::INTERCEPTOR: 377 case LookupIterator::INTERCEPTOR:
370 case LookupIterator::JSPROXY: 378 case LookupIterator::JSPROXY:
371 case LookupIterator::NOT_FOUND: 379 case LookupIterator::NOT_FOUND:
372 case LookupIterator::INTEGER_INDEXED_EXOTIC: 380 case LookupIterator::INTEGER_INDEXED_EXOTIC:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 // Find the top object. 425 // Find the top object.
418 Handle<JSObject> last; 426 Handle<JSObject> last;
419 PrototypeIterator iter(isolate(), holder()); 427 PrototypeIterator iter(isolate(), holder());
420 while (!iter.IsAtEnd()) { 428 while (!iter.IsAtEnd()) {
421 last = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 429 last = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
422 iter.Advance(); 430 iter.Advance();
423 } 431 }
424 if (!last.is_null()) set_holder(last); 432 if (!last.is_null()) set_holder(last);
425 NonexistentFrontendHeader(name, &miss, scratch1(), scratch2()); 433 NonexistentFrontendHeader(name, &miss, scratch1(), scratch2());
426 } else { 434 } else {
427 FrontendHeader(receiver(), name, &miss); 435 FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING);
428 DCHECK(holder()->HasFastProperties()); 436 DCHECK(holder()->HasFastProperties());
429 } 437 }
430 438
431 int descriptor = transition->LastAdded(); 439 int descriptor = transition->LastAdded();
432 Handle<DescriptorArray> descriptors(transition->instance_descriptors()); 440 Handle<DescriptorArray> descriptors(transition->instance_descriptors());
433 PropertyDetails details = descriptors->GetDetails(descriptor); 441 PropertyDetails details = descriptors->GetDetails(descriptor);
434 Representation representation = details.representation(); 442 Representation representation = details.representation();
435 DCHECK(!representation.IsNone()); 443 DCHECK(!representation.IsNone());
436 444
437 // Stub is never generated for objects that require access checks. 445 // Stub is never generated for objects that require access checks.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 DCHECK(elements_kind == DICTIONARY_ELEMENTS); 545 DCHECK(elements_kind == DICTIONARY_ELEMENTS);
538 cached_stub = LoadDictionaryElementStub(isolate()).GetCode(); 546 cached_stub = LoadDictionaryElementStub(isolate()).GetCode();
539 } 547 }
540 } 548 }
541 549
542 handlers->Add(cached_stub); 550 handlers->Add(cached_stub);
543 } 551 }
544 } 552 }
545 } 553 }
546 } // namespace v8::internal 554 } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698