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

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

Issue 2357163003: [ic][ia32][x87] Pass value, slot and vector to StoreIC and KeyedStoreIC through the stack. (Closed)
Patch Set: Created 4 years, 3 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/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.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/ic-inl.h" 10 #include "src/ic/ic-inl.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 Handle<Name> name, 122 Handle<Name> name,
123 Label* miss, 123 Label* miss,
124 ReturnHolder return_what) { 124 ReturnHolder return_what) {
125 return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name, 125 return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name,
126 miss, SKIP_RECEIVER, return_what); 126 miss, SKIP_RECEIVER, return_what);
127 } 127 }
128 128
129 129
130 Register PropertyHandlerCompiler::Frontend(Handle<Name> name) { 130 Register PropertyHandlerCompiler::Frontend(Handle<Name> name) {
131 Label miss; 131 Label miss;
132 if (IC::ICUseVector(kind())) { 132 if (IC::ShouldPushPopSlotAndVector(kind())) {
133 PushVectorAndSlot(); 133 PushVectorAndSlot();
134 } 134 }
135 Register reg = FrontendHeader(receiver(), name, &miss, RETURN_HOLDER); 135 Register reg = FrontendHeader(receiver(), name, &miss, RETURN_HOLDER);
136 FrontendFooter(name, &miss); 136 FrontendFooter(name, &miss);
137 // The footer consumes the vector and slot from the stack if miss occurs. 137 // The footer consumes the vector and slot from the stack if miss occurs.
138 if (IC::ICUseVector(kind())) { 138 if (IC::ShouldPushPopSlotAndVector(kind())) {
139 DiscardVectorAndSlot(); 139 DiscardVectorAndSlot();
140 } 140 }
141 return reg; 141 return reg;
142 } 142 }
143 143
144 144
145 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name, 145 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name,
146 Label* miss, 146 Label* miss,
147 Register scratch1, 147 Register scratch1,
148 Register scratch2) { 148 Register scratch2) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 __ Move(receiver(), reg); 202 __ Move(receiver(), reg);
203 LoadConstantStub stub(isolate(), constant_index); 203 LoadConstantStub stub(isolate(), constant_index);
204 GenerateTailCall(masm(), stub.GetCode()); 204 GenerateTailCall(masm(), stub.GetCode());
205 return GetCode(kind(), name); 205 return GetCode(kind(), name);
206 } 206 }
207 207
208 208
209 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 209 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
210 Handle<Name> name) { 210 Handle<Name> name) {
211 Label miss; 211 Label miss;
212 if (IC::ICUseVector(kind())) { 212 if (IC::ShouldPushPopSlotAndVector(kind())) {
213 DCHECK(kind() == Code::LOAD_IC); 213 DCHECK(kind() == Code::LOAD_IC);
214 PushVectorAndSlot(); 214 PushVectorAndSlot();
215 } 215 }
216 NonexistentFrontendHeader(name, &miss, scratch2(), scratch3()); 216 NonexistentFrontendHeader(name, &miss, scratch2(), scratch3());
217 if (IC::ICUseVector(kind())) { 217 if (IC::ShouldPushPopSlotAndVector(kind())) {
218 DiscardVectorAndSlot(); 218 DiscardVectorAndSlot();
219 } 219 }
220 GenerateLoadConstant(isolate()->factory()->undefined_value()); 220 GenerateLoadConstant(isolate()->factory()->undefined_value());
221 FrontendFooter(name, &miss); 221 FrontendFooter(name, &miss);
222 return GetCode(kind(), name); 222 return GetCode(kind(), name);
223 } 223 }
224 224
225 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 225 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
226 Handle<Name> name, Handle<AccessorInfo> callback, Handle<Code> slow_stub) { 226 Handle<Name> name, Handle<AccessorInfo> callback, Handle<Code> slow_stub) {
227 if (FLAG_runtime_call_stats) { 227 if (FLAG_runtime_call_stats) {
(...skipping 12 matching lines...) Expand all
240 GenerateTailCall(masm(), slow_stub); 240 GenerateTailCall(masm(), slow_stub);
241 } 241 }
242 Register holder = Frontend(name); 242 Register holder = Frontend(name);
243 GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(), 243 GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(),
244 scratch2(), false, no_reg, holder, accessor_index); 244 scratch2(), false, no_reg, holder, accessor_index);
245 return GetCode(kind(), name); 245 return GetCode(kind(), name);
246 } 246 }
247 247
248 248
249 void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) { 249 void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) {
250 if (IC::ICUseVector(kind())) { 250 if (IC::ShouldPushPopSlotAndVector(kind())) {
251 if (holder_reg.is(receiver())) { 251 if (holder_reg.is(receiver())) {
252 PushVectorAndSlot(); 252 PushVectorAndSlot();
253 } else { 253 } else {
254 DCHECK(holder_reg.is(scratch1())); 254 DCHECK(holder_reg.is(scratch1()));
255 PushVectorAndSlot(scratch2(), scratch3()); 255 PushVectorAndSlot(scratch2(), scratch3());
256 } 256 }
257 } 257 }
258 } 258 }
259 259
260 260
261 void NamedLoadHandlerCompiler::InterceptorVectorSlotPop(Register holder_reg, 261 void NamedLoadHandlerCompiler::InterceptorVectorSlotPop(Register holder_reg,
262 PopMode mode) { 262 PopMode mode) {
263 if (IC::ICUseVector(kind())) { 263 if (IC::ShouldPushPopSlotAndVector(kind())) {
264 if (mode == DISCARD) { 264 if (mode == DISCARD) {
265 DiscardVectorAndSlot(); 265 DiscardVectorAndSlot();
266 } else { 266 } else {
267 if (holder_reg.is(receiver())) { 267 if (holder_reg.is(receiver())) {
268 PopVectorAndSlot(); 268 PopVectorAndSlot();
269 } else { 269 } else {
270 DCHECK(holder_reg.is(scratch1())); 270 DCHECK(holder_reg.is(scratch1()));
271 PopVectorAndSlot(scratch2(), scratch3()); 271 PopVectorAndSlot(scratch2(), scratch3());
272 } 272 }
273 } 273 }
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 expected_arguments, scratch2()); 431 expected_arguments, scratch2());
432 return GetCode(kind(), name); 432 return GetCode(kind(), name);
433 } 433 }
434 434
435 435
436 // TODO(verwaest): Cleanup. holder() is actually the receiver. 436 // TODO(verwaest): Cleanup. holder() is actually the receiver.
437 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( 437 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
438 Handle<Map> transition, Handle<Name> name) { 438 Handle<Map> transition, Handle<Name> name) {
439 Label miss; 439 Label miss;
440 440
441 bool vector_and_slot_on_stack = 441 // Ensure that the StoreTransitionStub we are going to call has the same
442 StoreTransitionDescriptor::PassVectorAndSlotOnStack(); 442 // number of stack arguments. This means that we don't have to adapt them
443 if (vector_and_slot_on_stack) { 443 // if we decide to call the transition or miss stub.
444 // Speculatively prepare for calling StoreTransitionStub by converting 444 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount ==
445 // StoreWithVectorDescriptor arguments to StoreTransitionDescriptor 445 StoreTransitionDescriptor::kStackArgumentsCount);
446 // arguments. 446 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 0 ||
447 PopReturnAddress(this->name()); 447 StoreWithVectorDescriptor::kStackArgumentsCount == 3);
448 PushVectorAndSlot(); 448 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
449 PushReturnAddress(this->name()); 449 StoreWithVectorDescriptor::kValue ==
450 } else { 450 StoreTransitionDescriptor::kParameterCount -
451 StoreTransitionDescriptor::kValue);
452 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
453 StoreWithVectorDescriptor::kSlot ==
454 StoreTransitionDescriptor::kParameterCount -
455 StoreTransitionDescriptor::kSlot);
456 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
457 StoreWithVectorDescriptor::kVector ==
458 StoreTransitionDescriptor::kParameterCount -
459 StoreTransitionDescriptor::kVector);
460
461 bool need_save_restore = IC::ShouldPushPopSlotAndVector(kind());
462 if (need_save_restore) {
451 PushVectorAndSlot(); 463 PushVectorAndSlot();
452 } 464 }
453 465
454 // Check that we are allowed to write this. 466 // Check that we are allowed to write this.
455 bool is_nonexistent = holder()->map() == transition->GetBackPointer(); 467 bool is_nonexistent = holder()->map() == transition->GetBackPointer();
456 if (is_nonexistent) { 468 if (is_nonexistent) {
457 // Find the top object. 469 // Find the top object.
458 Handle<JSObject> last; 470 Handle<JSObject> last;
459 PrototypeIterator::WhereToEnd end = 471 PrototypeIterator::WhereToEnd end =
460 name->IsPrivate() ? PrototypeIterator::END_AT_NON_HIDDEN 472 name->IsPrivate() ? PrototypeIterator::END_AT_NON_HIDDEN
(...skipping 19 matching lines...) Expand all
480 // Stub is never generated for objects that require access checks. 492 // Stub is never generated for objects that require access checks.
481 DCHECK(!transition->is_access_check_needed()); 493 DCHECK(!transition->is_access_check_needed());
482 494
483 // Call to respective StoreTransitionStub. 495 // Call to respective StoreTransitionStub.
484 Register map_reg = StoreTransitionDescriptor::MapRegister(); 496 Register map_reg = StoreTransitionDescriptor::MapRegister();
485 497
486 if (details.type() == DATA_CONSTANT) { 498 if (details.type() == DATA_CONSTANT) {
487 DCHECK(descriptors->GetValue(descriptor)->IsJSFunction()); 499 DCHECK(descriptors->GetValue(descriptor)->IsJSFunction());
488 GenerateRestoreMap(transition, map_reg, scratch1(), &miss); 500 GenerateRestoreMap(transition, map_reg, scratch1(), &miss);
489 GenerateConstantCheck(map_reg, descriptor, value(), scratch1(), &miss); 501 GenerateConstantCheck(map_reg, descriptor, value(), scratch1(), &miss);
490 if (!vector_and_slot_on_stack) { 502 if (need_save_restore) {
491 PopVectorAndSlot(); 503 PopVectorAndSlot();
492 } 504 }
493 GenerateRestoreName(name); 505 GenerateRestoreName(name);
494 StoreTransitionStub stub(isolate()); 506 StoreTransitionStub stub(isolate());
495 GenerateTailCall(masm(), stub.GetCode()); 507 GenerateTailCall(masm(), stub.GetCode());
496 508
497 } else { 509 } else {
498 if (representation.IsHeapObject()) { 510 if (representation.IsHeapObject()) {
499 GenerateFieldTypeChecks(descriptors->GetFieldType(descriptor), value(), 511 GenerateFieldTypeChecks(descriptors->GetFieldType(descriptor), value(),
500 &miss); 512 &miss);
501 } 513 }
502 StoreTransitionStub::StoreMode store_mode = 514 StoreTransitionStub::StoreMode store_mode =
503 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0 515 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0
504 ? StoreTransitionStub::ExtendStorageAndStoreMapAndValue 516 ? StoreTransitionStub::ExtendStorageAndStoreMapAndValue
505 : StoreTransitionStub::StoreMapAndValue; 517 : StoreTransitionStub::StoreMapAndValue;
506 GenerateRestoreMap(transition, map_reg, scratch1(), &miss); 518 GenerateRestoreMap(transition, map_reg, scratch1(), &miss);
507 if (!vector_and_slot_on_stack) { 519 if (need_save_restore) {
508 PopVectorAndSlot(); 520 PopVectorAndSlot();
509 } 521 }
510 GenerateRestoreName(name); 522 GenerateRestoreName(name);
511 StoreTransitionStub stub(isolate(), 523 StoreTransitionStub stub(isolate(),
512 FieldIndex::ForDescriptor(*transition, descriptor), 524 FieldIndex::ForDescriptor(*transition, descriptor),
513 representation, store_mode); 525 representation, store_mode);
514 GenerateTailCall(masm(), stub.GetCode()); 526 GenerateTailCall(masm(), stub.GetCode());
515 } 527 }
516 528
517 __ bind(&miss); 529 __ bind(&miss);
518 if (vector_and_slot_on_stack) { 530 if (need_save_restore) {
519 // Prepare for calling miss builtin with StoreWithVectorDescriptor.
520 PopReturnAddress(this->name());
521 PopVectorAndSlot();
522 PushReturnAddress(this->name());
523 } else {
524 PopVectorAndSlot(); 531 PopVectorAndSlot();
525 } 532 }
526 GenerateRestoreName(name); 533 GenerateRestoreName(name);
527 TailCallBuiltin(masm(), MissBuiltin(kind())); 534 TailCallBuiltin(masm(), MissBuiltin(kind()));
528 535
529 return GetCode(kind(), name); 536 return GetCode(kind(), name);
530 } 537 }
531 538
532 bool NamedStoreHandlerCompiler::RequiresFieldTypeChecks( 539 bool NamedStoreHandlerCompiler::RequiresFieldTypeChecks(
533 FieldType* field_type) const { 540 FieldType* field_type) const {
534 return field_type->IsClass(); 541 return field_type->IsClass();
535 } 542 }
536 543
537 544
538 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) { 545 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) {
539 Label miss; 546 Label miss;
540 DCHECK(it->representation().IsHeapObject()); 547 DCHECK(it->representation().IsHeapObject());
541 548
542 FieldType* field_type = *it->GetFieldType(); 549 FieldType* field_type = *it->GetFieldType();
543 bool need_save_restore = false; 550 bool need_save_restore = false;
544 if (RequiresFieldTypeChecks(field_type)) { 551 if (RequiresFieldTypeChecks(field_type)) {
545 need_save_restore = IC::ICUseVector(kind()); 552 need_save_restore = IC::ShouldPushPopSlotAndVector(kind());
546 if (need_save_restore) PushVectorAndSlot(); 553 if (need_save_restore) PushVectorAndSlot();
547 GenerateFieldTypeChecks(field_type, value(), &miss); 554 GenerateFieldTypeChecks(field_type, value(), &miss);
548 if (need_save_restore) PopVectorAndSlot(); 555 if (need_save_restore) PopVectorAndSlot();
549 } 556 }
550 557
551 StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation()); 558 StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation());
552 GenerateTailCall(masm(), stub.GetCode()); 559 GenerateTailCall(masm(), stub.GetCode());
553 560
554 __ bind(&miss); 561 __ bind(&miss);
555 if (need_save_restore) PopVectorAndSlot(); 562 if (need_save_restore) PopVectorAndSlot();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 } 649 }
643 650
644 void ElementHandlerCompiler::CompileElementHandlers( 651 void ElementHandlerCompiler::CompileElementHandlers(
645 MapHandleList* receiver_maps, List<Handle<Object>>* handlers) { 652 MapHandleList* receiver_maps, List<Handle<Object>>* handlers) {
646 for (int i = 0; i < receiver_maps->length(); ++i) { 653 for (int i = 0; i < receiver_maps->length(); ++i) {
647 handlers->Add(GetKeyedLoadHandler(receiver_maps->at(i), isolate())); 654 handlers->Add(GetKeyedLoadHandler(receiver_maps->at(i), isolate()));
648 } 655 }
649 } 656 }
650 } // namespace internal 657 } // namespace internal
651 } // namespace v8 658 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698