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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 430783002: Cleanup in stub-cache.cc; remove unused ArrayLength store ICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Port Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/arm64/stub-cache-arm64.cc ('k') | src/ic.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic-inl.h" 10 #include "src/ic-inl.h"
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 // Put api_function_address in place. 363 // Put api_function_address in place.
364 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 364 Address function_address = v8::ToCData<Address>(api_call_info->callback());
365 __ mov(api_function_address, Immediate(function_address)); 365 __ mov(api_function_address, Immediate(function_address));
366 366
367 // Jump to stub. 367 // Jump to stub.
368 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 368 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
369 __ TailCallStub(&stub); 369 __ TailCallStub(&stub);
370 } 370 }
371 371
372 372
373 void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm,
374 Label* label,
375 Handle<Name> name) {
376 if (!label->is_unused()) {
377 __ bind(label);
378 __ mov(this->name(), Immediate(name));
379 }
380 }
381
382
383 // Generate code to check that a global property cell is empty. Create 373 // Generate code to check that a global property cell is empty. Create
384 // the property cell at compilation time if no cell exists for the 374 // the property cell at compilation time if no cell exists for the
385 // property. 375 // property.
386 void PropertyHandlerCompiler::GenerateCheckPropertyCell( 376 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
387 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 377 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
388 Register scratch, Label* miss) { 378 Register scratch, Label* miss) {
389 Handle<PropertyCell> cell = 379 Handle<PropertyCell> cell =
390 JSGlobalObject::EnsurePropertyCell(global, name); 380 JSGlobalObject::EnsurePropertyCell(global, name);
391 ASSERT(cell->value()->IsTheHole()); 381 ASSERT(cell->value()->IsTheHole());
392 Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value(); 382 Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value();
393 if (masm->serializer_enabled()) { 383 if (masm->serializer_enabled()) {
394 __ mov(scratch, Immediate(cell)); 384 __ mov(scratch, Immediate(cell));
395 __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset), 385 __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset),
396 Immediate(the_hole)); 386 Immediate(the_hole));
397 } else { 387 } else {
398 __ cmp(Operand::ForCell(cell), Immediate(the_hole)); 388 __ cmp(Operand::ForCell(cell), Immediate(the_hole));
399 } 389 }
400 __ j(not_equal, miss); 390 __ j(not_equal, miss);
401 } 391 }
402 392
403 393
394 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
395 Handle<Code> code) {
396 __ jmp(code, RelocInfo::CODE_TARGET);
397 }
398
399
400 #undef __
401 #define __ ACCESS_MASM(masm())
402
403
404 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
405 Handle<Name> name) {
406 if (!label->is_unused()) {
407 __ bind(label);
408 __ mov(this->name(), Immediate(name));
409 }
410 }
411
412
404 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( 413 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
405 MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, 414 Register holder_reg, Handle<Name> name, Label* miss) {
406 Handle<Name> name, Label* miss) { 415 if (holder()->IsJSGlobalObject()) {
407 if (holder->IsJSGlobalObject()) { 416 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(holder()),
408 GenerateCheckPropertyCell( 417 name, scratch1(), miss);
409 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); 418 } else if (!holder()->HasFastProperties()) {
410 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 419 GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1(),
411 GenerateDictionaryNegativeLookup( 420 scratch2());
412 masm, miss, holder_reg, name, scratch1(), scratch2());
413 } 421 }
414 } 422 }
415 423
416 424
417 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 425 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
418 // store is successful. 426 // store is successful.
419 void NamedStoreHandlerCompiler::GenerateStoreTransition( 427 void NamedStoreHandlerCompiler::GenerateStoreTransition(
420 MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition, 428 Handle<Map> transition, Handle<Name> name, Register receiver_reg,
421 Handle<Name> name, Register receiver_reg, Register storage_reg, 429 Register storage_reg, Register value_reg, Register scratch1,
422 Register value_reg, Register scratch1, Register scratch2, Register unused, 430 Register scratch2, Register unused, Label* miss_label, Label* slow) {
423 Label* miss_label, Label* slow) {
424 int descriptor = transition->LastAdded(); 431 int descriptor = transition->LastAdded();
425 DescriptorArray* descriptors = transition->instance_descriptors(); 432 DescriptorArray* descriptors = transition->instance_descriptors();
426 PropertyDetails details = descriptors->GetDetails(descriptor); 433 PropertyDetails details = descriptors->GetDetails(descriptor);
427 Representation representation = details.representation(); 434 Representation representation = details.representation();
428 ASSERT(!representation.IsNone()); 435 ASSERT(!representation.IsNone());
429 436
430 if (details.type() == CONSTANT) { 437 if (details.type() == CONSTANT) {
431 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 438 Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
432 __ CmpObject(value_reg, constant); 439 __ CmpObject(value_reg, constant);
433 __ j(not_equal, miss_label); 440 __ j(not_equal, miss_label);
434 } else if (representation.IsSmi()) { 441 } else if (representation.IsSmi()) {
435 __ JumpIfNotSmi(value_reg, miss_label); 442 __ JumpIfNotSmi(value_reg, miss_label);
436 } else if (representation.IsHeapObject()) { 443 } else if (representation.IsHeapObject()) {
437 __ JumpIfSmi(value_reg, miss_label); 444 __ JumpIfSmi(value_reg, miss_label);
438 HeapType* field_type = descriptors->GetFieldType(descriptor); 445 HeapType* field_type = descriptors->GetFieldType(descriptor);
439 HeapType::Iterator<Map> it = field_type->Classes(); 446 HeapType::Iterator<Map> it = field_type->Classes();
440 if (!it.Done()) { 447 if (!it.Done()) {
441 Label do_store; 448 Label do_store;
(...skipping 12 matching lines...) Expand all
454 Label do_store, heap_number; 461 Label do_store, heap_number;
455 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow, MUTABLE); 462 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow, MUTABLE);
456 463
457 __ JumpIfNotSmi(value_reg, &heap_number); 464 __ JumpIfNotSmi(value_reg, &heap_number);
458 __ SmiUntag(value_reg); 465 __ SmiUntag(value_reg);
459 __ Cvtsi2sd(xmm0, value_reg); 466 __ Cvtsi2sd(xmm0, value_reg);
460 __ SmiTag(value_reg); 467 __ SmiTag(value_reg);
461 __ jmp(&do_store); 468 __ jmp(&do_store);
462 469
463 __ bind(&heap_number); 470 __ bind(&heap_number);
464 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 471 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
465 miss_label, DONT_DO_SMI_CHECK); 472 DONT_DO_SMI_CHECK);
466 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 473 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
467 474
468 __ bind(&do_store); 475 __ bind(&do_store);
469 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 476 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
470 } 477 }
471 478
472 // Stub never generated for objects that require access checks. 479 // Stub never generated for objects that require access checks.
473 ASSERT(!transition->is_access_check_needed()); 480 ASSERT(!transition->is_access_check_needed());
474 481
475 // Perform map transition for the receiver if necessary. 482 // Perform map transition for the receiver if necessary.
476 if (details.type() == FIELD && 483 if (details.type() == FIELD &&
477 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) { 484 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
478 // The properties must be extended before we can store the value. 485 // The properties must be extended before we can store the value.
479 // We jump to a runtime call that extends the properties array. 486 // We jump to a runtime call that extends the properties array.
480 __ pop(scratch1); // Return address. 487 __ pop(scratch1); // Return address.
481 __ push(receiver_reg); 488 __ push(receiver_reg);
482 __ push(Immediate(transition)); 489 __ push(Immediate(transition));
483 __ push(value_reg); 490 __ push(value_reg);
484 __ push(scratch1); 491 __ push(scratch1);
485 __ TailCallExternalReference( 492 __ TailCallExternalReference(
486 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 493 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
487 masm->isolate()), 494 isolate()),
488 3, 495 3, 1);
489 1);
490 return; 496 return;
491 } 497 }
492 498
493 // Update the map of the object. 499 // Update the map of the object.
494 __ mov(scratch1, Immediate(transition)); 500 __ mov(scratch1, Immediate(transition));
495 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); 501 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
496 502
497 // Update the write barrier for the map field. 503 // Update the write barrier for the map field.
498 __ RecordWriteField(receiver_reg, 504 __ RecordWriteField(receiver_reg,
499 HeapObject::kMapOffset, 505 HeapObject::kMapOffset,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 576
571 // Return the value (register eax). 577 // Return the value (register eax).
572 ASSERT(value_reg.is(eax)); 578 ASSERT(value_reg.is(eax));
573 __ ret(0); 579 __ ret(0);
574 } 580 }
575 581
576 582
577 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 583 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
578 // but may be destroyed if store is successful. 584 // but may be destroyed if store is successful.
579 void NamedStoreHandlerCompiler::GenerateStoreField( 585 void NamedStoreHandlerCompiler::GenerateStoreField(
580 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, 586 Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
581 Register receiver_reg, Register name_reg, Register value_reg, 587 Register name_reg, Register value_reg, Register scratch1, Register scratch2,
582 Register scratch1, Register scratch2, Label* miss_label) { 588 Label* miss_label) {
583 // Stub never generated for non-global objects that require access 589 // Stub never generated for objects that require access checks.
584 // checks. 590 ASSERT(!object->IsAccessCheckNeeded());
585 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 591 ASSERT(!object->IsJSGlobalProxy());
586 592
587 FieldIndex index = lookup->GetFieldIndex(); 593 FieldIndex index = lookup->GetFieldIndex();
588 594
589 Representation representation = lookup->representation(); 595 Representation representation = lookup->representation();
590 ASSERT(!representation.IsNone()); 596 ASSERT(!representation.IsNone());
591 if (representation.IsSmi()) { 597 if (representation.IsSmi()) {
592 __ JumpIfNotSmi(value_reg, miss_label); 598 __ JumpIfNotSmi(value_reg, miss_label);
593 } else if (representation.IsHeapObject()) { 599 } else if (representation.IsHeapObject()) {
594 __ JumpIfSmi(value_reg, miss_label); 600 __ JumpIfSmi(value_reg, miss_label);
595 HeapType* field_type = lookup->GetFieldType(); 601 HeapType* field_type = lookup->GetFieldType();
(...skipping 21 matching lines...) Expand all
617 } 623 }
618 624
619 // Store the value into the storage. 625 // Store the value into the storage.
620 Label do_store, heap_number; 626 Label do_store, heap_number;
621 __ JumpIfNotSmi(value_reg, &heap_number); 627 __ JumpIfNotSmi(value_reg, &heap_number);
622 __ SmiUntag(value_reg); 628 __ SmiUntag(value_reg);
623 __ Cvtsi2sd(xmm0, value_reg); 629 __ Cvtsi2sd(xmm0, value_reg);
624 __ SmiTag(value_reg); 630 __ SmiTag(value_reg);
625 __ jmp(&do_store); 631 __ jmp(&do_store);
626 __ bind(&heap_number); 632 __ bind(&heap_number);
627 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 633 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
628 miss_label, DONT_DO_SMI_CHECK); 634 DONT_DO_SMI_CHECK);
629 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 635 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
630 __ bind(&do_store); 636 __ bind(&do_store);
631 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); 637 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0);
632 // Return the value (register eax). 638 // Return the value (register eax).
633 ASSERT(value_reg.is(eax)); 639 ASSERT(value_reg.is(eax));
634 __ ret(0); 640 __ ret(0);
635 return; 641 return;
636 } 642 }
637 643
638 ASSERT(!representation.IsDouble()); 644 ASSERT(!representation.IsDouble());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 smi_check); 680 smi_check);
675 } 681 }
676 } 682 }
677 683
678 // Return the value (register eax). 684 // Return the value (register eax).
679 ASSERT(value_reg.is(eax)); 685 ASSERT(value_reg.is(eax));
680 __ ret(0); 686 __ ret(0);
681 } 687 }
682 688
683 689
684 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
685 Handle<Code> code) {
686 __ jmp(code, RelocInfo::CODE_TARGET);
687 }
688
689
690 #undef __
691 #define __ ACCESS_MASM(masm())
692
693
694 Register PropertyHandlerCompiler::CheckPrototypes( 690 Register PropertyHandlerCompiler::CheckPrototypes(
695 Register object_reg, Register holder_reg, Register scratch1, 691 Register object_reg, Register holder_reg, Register scratch1,
696 Register scratch2, Handle<Name> name, Label* miss, 692 Register scratch2, Handle<Name> name, Label* miss,
697 PrototypeCheckType check) { 693 PrototypeCheckType check) {
698 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 694 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
699 695
700 // Make sure there's no overlap between holder and object registers. 696 // Make sure there's no overlap between holder and object registers.
701 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 697 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
702 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 698 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
703 && !scratch2.is(scratch1)); 699 && !scratch2.is(scratch1));
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 TailCallBuiltin(masm(), MissBuiltin(kind())); 805 TailCallBuiltin(masm(), MissBuiltin(kind()));
810 __ bind(&success); 806 __ bind(&success);
811 } 807 }
812 } 808 }
813 809
814 810
815 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 811 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
816 if (!miss->is_unused()) { 812 if (!miss->is_unused()) {
817 Label success; 813 Label success;
818 __ jmp(&success); 814 __ jmp(&success);
819 GenerateRestoreName(masm(), miss, name); 815 GenerateRestoreName(miss, name);
820 TailCallBuiltin(masm(), MissBuiltin(kind())); 816 TailCallBuiltin(masm(), MissBuiltin(kind()));
821 __ bind(&success); 817 __ bind(&success);
822 } 818 }
823 } 819 }
824 820
825 821
826 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg, 822 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
827 Handle<Name> name, 823 Handle<Name> name,
828 Handle<Object> callback) { 824 Handle<Object> callback) {
829 Label miss; 825 Label miss;
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 // Do tail-call to the runtime system. 1118 // Do tail-call to the runtime system.
1123 ExternalReference store_ic_property = ExternalReference( 1119 ExternalReference store_ic_property = ExternalReference(
1124 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 1120 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
1125 __ TailCallExternalReference(store_ic_property, 3, 1); 1121 __ TailCallExternalReference(store_ic_property, 3, 1);
1126 1122
1127 // Return the generated code. 1123 // Return the generated code.
1128 return GetCode(kind(), Code::FAST, name); 1124 return GetCode(kind(), Code::FAST, name);
1129 } 1125 }
1130 1126
1131 1127
1132 void NamedStoreHandlerCompiler::GenerateStoreArrayLength() {
1133 // Prepare tail call to StoreIC_ArrayLength.
1134 __ pop(scratch1()); // remove the return address
1135 __ push(receiver());
1136 __ push(value());
1137 __ push(scratch1()); // restore return address
1138
1139 ExternalReference ref =
1140 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength),
1141 masm()->isolate());
1142 __ TailCallExternalReference(ref, 2, 1);
1143 }
1144
1145
1146 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( 1128 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
1147 MapHandleList* receiver_maps, CodeHandleList* handler_stubs, 1129 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
1148 MapHandleList* transitioned_maps) { 1130 MapHandleList* transitioned_maps) {
1149 Label miss; 1131 Label miss;
1150 __ JumpIfSmi(receiver(), &miss, Label::kNear); 1132 __ JumpIfSmi(receiver(), &miss, Label::kNear);
1151 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); 1133 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
1152 for (int i = 0; i < receiver_maps->length(); ++i) { 1134 for (int i = 0; i < receiver_maps->length(); ++i) {
1153 __ cmp(scratch1(), receiver_maps->at(i)); 1135 __ cmp(scratch1(), receiver_maps->at(i));
1154 if (transitioned_maps->at(i).is_null()) { 1136 if (transitioned_maps->at(i).is_null()) {
1155 __ j(equal, handler_stubs->at(i)); 1137 __ j(equal, handler_stubs->at(i));
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 // ----------------------------------- 1373 // -----------------------------------
1392 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1374 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1393 } 1375 }
1394 1376
1395 1377
1396 #undef __ 1378 #undef __
1397 1379
1398 } } // namespace v8::internal 1380 } } // namespace v8::internal
1399 1381
1400 #endif // V8_TARGET_ARCH_IA32 1382 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm64/stub-cache-arm64.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698