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

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

Issue 438163003: X87: Cleanup in stub-cache.cc; remove unused ArrayLength store ICs. (Closed) Base URL: https://chromium.googlesource.com/external/v8.git@bleeding_edge
Patch Set: 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
« no previous file with comments | « no previous file | no next file » | 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_X87 7 #if V8_TARGET_ARCH_X87
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 DCHECK(cell->value()->IsTheHole()); 381 DCHECK(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 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 413 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
405 // store is successful. 414 // store is successful.
406 void NamedStoreHandlerCompiler::GenerateStoreTransition( 415 void NamedStoreHandlerCompiler::GenerateStoreTransition(
407 MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition, 416 Handle<Map> transition, Handle<Name> name, Register receiver_reg,
408 Handle<Name> name, Register receiver_reg, Register storage_reg, 417 Register storage_reg, Register value_reg, Register scratch1,
409 Register value_reg, Register scratch1, Register scratch2, Register unused, 418 Register scratch2, Register unused, Label* miss_label, Label* slow) {
410 Label* miss_label, Label* slow) {
411 int descriptor = transition->LastAdded(); 419 int descriptor = transition->LastAdded();
412 DescriptorArray* descriptors = transition->instance_descriptors(); 420 DescriptorArray* descriptors = transition->instance_descriptors();
413 PropertyDetails details = descriptors->GetDetails(descriptor); 421 PropertyDetails details = descriptors->GetDetails(descriptor);
414 Representation representation = details.representation(); 422 Representation representation = details.representation();
415 DCHECK(!representation.IsNone()); 423 DCHECK(!representation.IsNone());
416 424
417 if (details.type() == CONSTANT) { 425 if (details.type() == CONSTANT) {
418 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 426 Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
419 __ CmpObject(value_reg, constant); 427 __ CmpObject(value_reg, constant);
420 __ j(not_equal, miss_label); 428 __ j(not_equal, miss_label);
421 } else if (representation.IsSmi()) { 429 } else if (representation.IsSmi()) {
422 __ JumpIfNotSmi(value_reg, miss_label); 430 __ JumpIfNotSmi(value_reg, miss_label);
423 } else if (representation.IsHeapObject()) { 431 } else if (representation.IsHeapObject()) {
424 __ JumpIfSmi(value_reg, miss_label); 432 __ JumpIfSmi(value_reg, miss_label);
425 HeapType* field_type = descriptors->GetFieldType(descriptor); 433 HeapType* field_type = descriptors->GetFieldType(descriptor);
426 HeapType::Iterator<Map> it = field_type->Classes(); 434 HeapType::Iterator<Map> it = field_type->Classes();
427 if (!it.Done()) { 435 if (!it.Done()) {
428 Label do_store; 436 Label do_store;
(...skipping 14 matching lines...) Expand all
443 451
444 __ JumpIfNotSmi(value_reg, &heap_number); 452 __ JumpIfNotSmi(value_reg, &heap_number);
445 __ SmiUntag(value_reg); 453 __ SmiUntag(value_reg);
446 __ push(value_reg); 454 __ push(value_reg);
447 __ fild_s(Operand(esp, 0)); 455 __ fild_s(Operand(esp, 0));
448 __ pop(value_reg); 456 __ pop(value_reg);
449 __ SmiTag(value_reg); 457 __ SmiTag(value_reg);
450 __ jmp(&do_store); 458 __ jmp(&do_store);
451 459
452 __ bind(&heap_number); 460 __ bind(&heap_number);
453 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 461 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
454 miss_label, DONT_DO_SMI_CHECK); 462 DONT_DO_SMI_CHECK);
455 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset)); 463 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset));
456 464
457 __ bind(&do_store); 465 __ bind(&do_store);
458 __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset)); 466 __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset));
459 } 467 }
460 468
461 // Stub never generated for objects that require access checks. 469 // Stub never generated for objects that require access checks.
462 DCHECK(!transition->is_access_check_needed()); 470 DCHECK(!transition->is_access_check_needed());
463 471
464 // Perform map transition for the receiver if necessary. 472 // Perform map transition for the receiver if necessary.
465 if (details.type() == FIELD && 473 if (details.type() == FIELD &&
466 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) { 474 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
467 // The properties must be extended before we can store the value. 475 // The properties must be extended before we can store the value.
468 // We jump to a runtime call that extends the properties array. 476 // We jump to a runtime call that extends the properties array.
469 __ pop(scratch1); // Return address. 477 __ pop(scratch1); // Return address.
470 __ push(receiver_reg); 478 __ push(receiver_reg);
471 __ push(Immediate(transition)); 479 __ push(Immediate(transition));
472 __ push(value_reg); 480 __ push(value_reg);
473 __ push(scratch1); 481 __ push(scratch1);
474 __ TailCallExternalReference( 482 __ TailCallExternalReference(
475 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 483 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
476 masm->isolate()), 484 isolate()),
477 3, 485 3, 1);
478 1);
479 return; 486 return;
480 } 487 }
481 488
482 // Update the map of the object. 489 // Update the map of the object.
483 __ mov(scratch1, Immediate(transition)); 490 __ mov(scratch1, Immediate(transition));
484 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); 491 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
485 492
486 // Update the write barrier for the map field. 493 // Update the write barrier for the map field.
487 __ RecordWriteField(receiver_reg, 494 __ RecordWriteField(receiver_reg,
488 HeapObject::kMapOffset, 495 HeapObject::kMapOffset,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 563
557 // Return the value (register eax). 564 // Return the value (register eax).
558 DCHECK(value_reg.is(eax)); 565 DCHECK(value_reg.is(eax));
559 __ ret(0); 566 __ ret(0);
560 } 567 }
561 568
562 569
563 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 570 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
564 // but may be destroyed if store is successful. 571 // but may be destroyed if store is successful.
565 void NamedStoreHandlerCompiler::GenerateStoreField( 572 void NamedStoreHandlerCompiler::GenerateStoreField(
566 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, 573 Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
567 Register receiver_reg, Register name_reg, Register value_reg, 574 Register name_reg, Register value_reg, Register scratch1, Register scratch2,
568 Register scratch1, Register scratch2, Label* miss_label) { 575 Label* miss_label) {
569 // Stub never generated for non-global objects that require access 576 // Stub never generated for objects that require access checks.
570 // checks. 577 DCHECK(!object->IsAccessCheckNeeded());
571 DCHECK(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 578 DCHECK(!object->IsJSGlobalProxy());
572 579
573 FieldIndex index = lookup->GetFieldIndex(); 580 FieldIndex index = lookup->GetFieldIndex();
574 581
575 Representation representation = lookup->representation(); 582 Representation representation = lookup->representation();
576 DCHECK(!representation.IsNone()); 583 DCHECK(!representation.IsNone());
577 if (representation.IsSmi()) { 584 if (representation.IsSmi()) {
578 __ JumpIfNotSmi(value_reg, miss_label); 585 __ JumpIfNotSmi(value_reg, miss_label);
579 } else if (representation.IsHeapObject()) { 586 } else if (representation.IsHeapObject()) {
580 __ JumpIfSmi(value_reg, miss_label); 587 __ JumpIfSmi(value_reg, miss_label);
581 HeapType* field_type = lookup->GetFieldType(); 588 HeapType* field_type = lookup->GetFieldType();
(...skipping 23 matching lines...) Expand all
605 // Store the value into the storage. 612 // Store the value into the storage.
606 Label do_store, heap_number; 613 Label do_store, heap_number;
607 __ JumpIfNotSmi(value_reg, &heap_number); 614 __ JumpIfNotSmi(value_reg, &heap_number);
608 __ SmiUntag(value_reg); 615 __ SmiUntag(value_reg);
609 __ push(value_reg); 616 __ push(value_reg);
610 __ fild_s(Operand(esp, 0)); 617 __ fild_s(Operand(esp, 0));
611 __ pop(value_reg); 618 __ pop(value_reg);
612 __ SmiTag(value_reg); 619 __ SmiTag(value_reg);
613 __ jmp(&do_store); 620 __ jmp(&do_store);
614 __ bind(&heap_number); 621 __ bind(&heap_number);
615 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 622 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
616 miss_label, DONT_DO_SMI_CHECK); 623 DONT_DO_SMI_CHECK);
617 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset)); 624 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset));
618 __ bind(&do_store); 625 __ bind(&do_store);
619 __ fstp_d(FieldOperand(scratch1, HeapNumber::kValueOffset)); 626 __ fstp_d(FieldOperand(scratch1, HeapNumber::kValueOffset));
620 // Return the value (register eax). 627 // Return the value (register eax).
621 DCHECK(value_reg.is(eax)); 628 DCHECK(value_reg.is(eax));
622 __ ret(0); 629 __ ret(0);
623 return; 630 return;
624 } 631 }
625 632
626 DCHECK(!representation.IsDouble()); 633 DCHECK(!representation.IsDouble());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 smi_check); 667 smi_check);
661 } 668 }
662 } 669 }
663 670
664 // Return the value (register eax). 671 // Return the value (register eax).
665 DCHECK(value_reg.is(eax)); 672 DCHECK(value_reg.is(eax));
666 __ ret(0); 673 __ ret(0);
667 } 674 }
668 675
669 676
670 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
671 Handle<Code> code) {
672 __ jmp(code, RelocInfo::CODE_TARGET);
673 }
674
675
676 #undef __
677 #define __ ACCESS_MASM(masm())
678
679
680 Register PropertyHandlerCompiler::CheckPrototypes( 677 Register PropertyHandlerCompiler::CheckPrototypes(
681 Register object_reg, Register holder_reg, Register scratch1, 678 Register object_reg, Register holder_reg, Register scratch1,
682 Register scratch2, Handle<Name> name, Label* miss, 679 Register scratch2, Handle<Name> name, Label* miss,
683 PrototypeCheckType check) { 680 PrototypeCheckType check) {
684 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 681 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
685 682
686 // Make sure there's no overlap between holder and object registers. 683 // Make sure there's no overlap between holder and object registers.
687 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 684 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
688 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 685 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
689 && !scratch2.is(scratch1)); 686 && !scratch2.is(scratch1));
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 TailCallBuiltin(masm(), MissBuiltin(kind())); 792 TailCallBuiltin(masm(), MissBuiltin(kind()));
796 __ bind(&success); 793 __ bind(&success);
797 } 794 }
798 } 795 }
799 796
800 797
801 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 798 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
802 if (!miss->is_unused()) { 799 if (!miss->is_unused()) {
803 Label success; 800 Label success;
804 __ jmp(&success); 801 __ jmp(&success);
805 GenerateRestoreName(masm(), miss, name); 802 GenerateRestoreName(miss, name);
806 TailCallBuiltin(masm(), MissBuiltin(kind())); 803 TailCallBuiltin(masm(), MissBuiltin(kind()));
807 __ bind(&success); 804 __ bind(&success);
808 } 805 }
809 } 806 }
810 807
811 808
812 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg, 809 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
813 Handle<Name> name, 810 Handle<Name> name,
814 Handle<Object> callback) { 811 Handle<Object> callback) {
815 Label miss; 812 Label miss;
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 // Do tail-call to the runtime system. 1105 // Do tail-call to the runtime system.
1109 ExternalReference store_ic_property = ExternalReference( 1106 ExternalReference store_ic_property = ExternalReference(
1110 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 1107 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
1111 __ TailCallExternalReference(store_ic_property, 3, 1); 1108 __ TailCallExternalReference(store_ic_property, 3, 1);
1112 1109
1113 // Return the generated code. 1110 // Return the generated code.
1114 return GetCode(kind(), Code::FAST, name); 1111 return GetCode(kind(), Code::FAST, name);
1115 } 1112 }
1116 1113
1117 1114
1118 void NamedStoreHandlerCompiler::GenerateStoreArrayLength() {
1119 // Prepare tail call to StoreIC_ArrayLength.
1120 __ pop(scratch1()); // remove the return address
1121 __ push(receiver());
1122 __ push(value());
1123 __ push(scratch1()); // restore return address
1124
1125 ExternalReference ref =
1126 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength),
1127 masm()->isolate());
1128 __ TailCallExternalReference(ref, 2, 1);
1129 }
1130
1131
1132 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( 1115 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
1133 MapHandleList* receiver_maps, CodeHandleList* handler_stubs, 1116 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
1134 MapHandleList* transitioned_maps) { 1117 MapHandleList* transitioned_maps) {
1135 Label miss; 1118 Label miss;
1136 __ JumpIfSmi(receiver(), &miss, Label::kNear); 1119 __ JumpIfSmi(receiver(), &miss, Label::kNear);
1137 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); 1120 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
1138 for (int i = 0; i < receiver_maps->length(); ++i) { 1121 for (int i = 0; i < receiver_maps->length(); ++i) {
1139 __ cmp(scratch1(), receiver_maps->at(i)); 1122 __ cmp(scratch1(), receiver_maps->at(i));
1140 if (transitioned_maps->at(i).is_null()) { 1123 if (transitioned_maps->at(i).is_null()) {
1141 __ j(equal, handler_stubs->at(i)); 1124 __ j(equal, handler_stubs->at(i));
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 // ----------------------------------- 1337 // -----------------------------------
1355 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1338 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1356 } 1339 }
1357 1340
1358 1341
1359 #undef __ 1342 #undef __
1360 1343
1361 } } // namespace v8::internal 1344 } } // namespace v8::internal
1362 1345
1363 #endif // V8_TARGET_ARCH_X87 1346 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698