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

Side by Side Diff: src/x64/stub-cache-x64.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/stub-cache.cc ('k') | 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_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 328 Address function_address = v8::ToCData<Address>(api_call_info->callback());
329 __ Move( 329 __ Move(
330 api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE); 330 api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE);
331 331
332 // Jump to stub. 332 // Jump to stub.
333 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 333 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
334 __ TailCallStub(&stub); 334 __ TailCallStub(&stub);
335 } 335 }
336 336
337 337
338 void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm,
339 Label* label,
340 Handle<Name> name) {
341 if (!label->is_unused()) {
342 __ bind(label);
343 __ Move(this->name(), name);
344 }
345 }
346
347
348 void PropertyHandlerCompiler::GenerateCheckPropertyCell( 338 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
349 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 339 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
350 Register scratch, Label* miss) { 340 Register scratch, Label* miss) {
351 Handle<PropertyCell> cell = 341 Handle<PropertyCell> cell =
352 JSGlobalObject::EnsurePropertyCell(global, name); 342 JSGlobalObject::EnsurePropertyCell(global, name);
353 ASSERT(cell->value()->IsTheHole()); 343 ASSERT(cell->value()->IsTheHole());
354 __ Move(scratch, cell); 344 __ Move(scratch, cell);
355 __ Cmp(FieldOperand(scratch, Cell::kValueOffset), 345 __ Cmp(FieldOperand(scratch, Cell::kValueOffset),
356 masm->isolate()->factory()->the_hole_value()); 346 masm->isolate()->factory()->the_hole_value());
357 __ j(not_equal, miss); 347 __ j(not_equal, miss);
358 } 348 }
359 349
360 350
351 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
352 Handle<Code> code) {
353 __ jmp(code, RelocInfo::CODE_TARGET);
354 }
355
356
357 #undef __
358 #define __ ACCESS_MASM((masm()))
359
360
361 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
362 Handle<Name> name) {
363 if (!label->is_unused()) {
364 __ bind(label);
365 __ Move(this->name(), name);
366 }
367 }
368
369
361 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( 370 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
362 MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, 371 Register holder_reg, Handle<Name> name, Label* miss) {
363 Handle<Name> name, Label* miss) { 372 if (holder()->IsJSGlobalObject()) {
364 if (holder->IsJSGlobalObject()) { 373 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(holder()),
365 GenerateCheckPropertyCell( 374 name, scratch1(), miss);
366 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); 375 } else if (!holder()->HasFastProperties()) {
367 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 376 GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1(),
368 GenerateDictionaryNegativeLookup( 377 scratch2());
369 masm, miss, holder_reg, name, scratch1(), scratch2());
370 } 378 }
371 } 379 }
372 380
373 381
374 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 382 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
375 // store is successful. 383 // store is successful.
376 void NamedStoreHandlerCompiler::GenerateStoreTransition( 384 void NamedStoreHandlerCompiler::GenerateStoreTransition(
377 MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition, 385 Handle<Map> transition, Handle<Name> name, Register receiver_reg,
378 Handle<Name> name, Register receiver_reg, Register storage_reg, 386 Register storage_reg, Register value_reg, Register scratch1,
379 Register value_reg, Register scratch1, Register scratch2, Register unused, 387 Register scratch2, Register unused, Label* miss_label, Label* slow) {
380 Label* miss_label, Label* slow) {
381 int descriptor = transition->LastAdded(); 388 int descriptor = transition->LastAdded();
382 DescriptorArray* descriptors = transition->instance_descriptors(); 389 DescriptorArray* descriptors = transition->instance_descriptors();
383 PropertyDetails details = descriptors->GetDetails(descriptor); 390 PropertyDetails details = descriptors->GetDetails(descriptor);
384 Representation representation = details.representation(); 391 Representation representation = details.representation();
385 ASSERT(!representation.IsNone()); 392 ASSERT(!representation.IsNone());
386 393
387 if (details.type() == CONSTANT) { 394 if (details.type() == CONSTANT) {
388 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 395 Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
389 __ Cmp(value_reg, constant); 396 __ Cmp(value_reg, constant);
390 __ j(not_equal, miss_label); 397 __ j(not_equal, miss_label);
391 } else if (representation.IsSmi()) { 398 } else if (representation.IsSmi()) {
392 __ JumpIfNotSmi(value_reg, miss_label); 399 __ JumpIfNotSmi(value_reg, miss_label);
393 } else if (representation.IsHeapObject()) { 400 } else if (representation.IsHeapObject()) {
394 __ JumpIfSmi(value_reg, miss_label); 401 __ JumpIfSmi(value_reg, miss_label);
395 HeapType* field_type = descriptors->GetFieldType(descriptor); 402 HeapType* field_type = descriptors->GetFieldType(descriptor);
396 HeapType::Iterator<Map> it = field_type->Classes(); 403 HeapType::Iterator<Map> it = field_type->Classes();
397 if (!it.Done()) { 404 if (!it.Done()) {
398 Label do_store; 405 Label do_store;
(...skipping 11 matching lines...) Expand all
410 } else if (representation.IsDouble()) { 417 } else if (representation.IsDouble()) {
411 Label do_store, heap_number; 418 Label do_store, heap_number;
412 __ AllocateHeapNumber(storage_reg, scratch1, slow, MUTABLE); 419 __ AllocateHeapNumber(storage_reg, scratch1, slow, MUTABLE);
413 420
414 __ JumpIfNotSmi(value_reg, &heap_number); 421 __ JumpIfNotSmi(value_reg, &heap_number);
415 __ SmiToInteger32(scratch1, value_reg); 422 __ SmiToInteger32(scratch1, value_reg);
416 __ Cvtlsi2sd(xmm0, scratch1); 423 __ Cvtlsi2sd(xmm0, scratch1);
417 __ jmp(&do_store); 424 __ jmp(&do_store);
418 425
419 __ bind(&heap_number); 426 __ bind(&heap_number);
420 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 427 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
421 miss_label, DONT_DO_SMI_CHECK); 428 DONT_DO_SMI_CHECK);
422 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 429 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
423 430
424 __ bind(&do_store); 431 __ bind(&do_store);
425 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 432 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
426 } 433 }
427 434
428 // Stub never generated for objects that require access checks. 435 // Stub never generated for objects that require access checks.
429 ASSERT(!transition->is_access_check_needed()); 436 ASSERT(!transition->is_access_check_needed());
430 437
431 // Perform map transition for the receiver if necessary. 438 // Perform map transition for the receiver if necessary.
432 if (details.type() == FIELD && 439 if (details.type() == FIELD &&
433 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) { 440 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
434 // The properties must be extended before we can store the value. 441 // The properties must be extended before we can store the value.
435 // We jump to a runtime call that extends the properties array. 442 // We jump to a runtime call that extends the properties array.
436 __ PopReturnAddressTo(scratch1); 443 __ PopReturnAddressTo(scratch1);
437 __ Push(receiver_reg); 444 __ Push(receiver_reg);
438 __ Push(transition); 445 __ Push(transition);
439 __ Push(value_reg); 446 __ Push(value_reg);
440 __ PushReturnAddressFrom(scratch1); 447 __ PushReturnAddressFrom(scratch1);
441 __ TailCallExternalReference( 448 __ TailCallExternalReference(
442 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 449 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
443 masm->isolate()), 450 isolate()),
444 3, 451 3, 1);
445 1);
446 return; 452 return;
447 } 453 }
448 454
449 // Update the map of the object. 455 // Update the map of the object.
450 __ Move(scratch1, transition); 456 __ Move(scratch1, transition);
451 __ movp(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); 457 __ movp(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
452 458
453 // Update the write barrier for the map field. 459 // Update the write barrier for the map field.
454 __ RecordWriteField(receiver_reg, 460 __ RecordWriteField(receiver_reg,
455 HeapObject::kMapOffset, 461 HeapObject::kMapOffset,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 524
519 // Return the value (register rax). 525 // Return the value (register rax).
520 ASSERT(value_reg.is(rax)); 526 ASSERT(value_reg.is(rax));
521 __ ret(0); 527 __ ret(0);
522 } 528 }
523 529
524 530
525 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 531 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
526 // but may be destroyed if store is successful. 532 // but may be destroyed if store is successful.
527 void NamedStoreHandlerCompiler::GenerateStoreField( 533 void NamedStoreHandlerCompiler::GenerateStoreField(
528 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, 534 Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
529 Register receiver_reg, Register name_reg, Register value_reg, 535 Register name_reg, Register value_reg, Register scratch1, Register scratch2,
530 Register scratch1, Register scratch2, Label* miss_label) { 536 Label* miss_label) {
531 // Stub never generated for non-global objects that require access 537 // Stub never generated for objects that require access checks.
532 // checks. 538 ASSERT(!object->IsAccessCheckNeeded());
533 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 539 ASSERT(!object->IsJSGlobalProxy());
534 540
535 FieldIndex index = lookup->GetFieldIndex(); 541 FieldIndex index = lookup->GetFieldIndex();
536 542
537 Representation representation = lookup->representation(); 543 Representation representation = lookup->representation();
538 ASSERT(!representation.IsNone()); 544 ASSERT(!representation.IsNone());
539 if (representation.IsSmi()) { 545 if (representation.IsSmi()) {
540 __ JumpIfNotSmi(value_reg, miss_label); 546 __ JumpIfNotSmi(value_reg, miss_label);
541 } else if (representation.IsHeapObject()) { 547 } else if (representation.IsHeapObject()) {
542 __ JumpIfSmi(value_reg, miss_label); 548 __ JumpIfSmi(value_reg, miss_label);
543 HeapType* field_type = lookup->GetFieldType(); 549 HeapType* field_type = lookup->GetFieldType();
(...skipping 22 matching lines...) Expand all
566 } 572 }
567 573
568 // Store the value into the storage. 574 // Store the value into the storage.
569 Label do_store, heap_number; 575 Label do_store, heap_number;
570 __ JumpIfNotSmi(value_reg, &heap_number); 576 __ JumpIfNotSmi(value_reg, &heap_number);
571 __ SmiToInteger32(scratch2, value_reg); 577 __ SmiToInteger32(scratch2, value_reg);
572 __ Cvtlsi2sd(xmm0, scratch2); 578 __ Cvtlsi2sd(xmm0, scratch2);
573 __ jmp(&do_store); 579 __ jmp(&do_store);
574 580
575 __ bind(&heap_number); 581 __ bind(&heap_number);
576 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 582 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
577 miss_label, DONT_DO_SMI_CHECK); 583 DONT_DO_SMI_CHECK);
578 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 584 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
579 __ bind(&do_store); 585 __ bind(&do_store);
580 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); 586 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0);
581 // Return the value (register rax). 587 // Return the value (register rax).
582 ASSERT(value_reg.is(rax)); 588 ASSERT(value_reg.is(rax));
583 __ ret(0); 589 __ ret(0);
584 return; 590 return;
585 } 591 }
586 592
587 // TODO(verwaest): Share this code as a code stub. 593 // TODO(verwaest): Share this code as a code stub.
(...skipping 26 matching lines...) Expand all
614 EMIT_REMEMBERED_SET, smi_check); 620 EMIT_REMEMBERED_SET, smi_check);
615 } 621 }
616 } 622 }
617 623
618 // Return the value (register rax). 624 // Return the value (register rax).
619 ASSERT(value_reg.is(rax)); 625 ASSERT(value_reg.is(rax));
620 __ ret(0); 626 __ ret(0);
621 } 627 }
622 628
623 629
624 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
625 Handle<Code> code) {
626 __ jmp(code, RelocInfo::CODE_TARGET);
627 }
628
629
630 #undef __
631 #define __ ACCESS_MASM((masm()))
632
633
634 Register PropertyHandlerCompiler::CheckPrototypes( 630 Register PropertyHandlerCompiler::CheckPrototypes(
635 Register object_reg, Register holder_reg, Register scratch1, 631 Register object_reg, Register holder_reg, Register scratch1,
636 Register scratch2, Handle<Name> name, Label* miss, 632 Register scratch2, Handle<Name> name, Label* miss,
637 PrototypeCheckType check) { 633 PrototypeCheckType check) {
638 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 634 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
639 635
640 // Make sure there's no overlap between holder and object registers. 636 // Make sure there's no overlap between holder and object registers.
641 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 637 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
642 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 638 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
643 && !scratch2.is(scratch1)); 639 && !scratch2.is(scratch1));
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 TailCallBuiltin(masm(), MissBuiltin(kind())); 746 TailCallBuiltin(masm(), MissBuiltin(kind()));
751 __ bind(&success); 747 __ bind(&success);
752 } 748 }
753 } 749 }
754 750
755 751
756 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 752 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
757 if (!miss->is_unused()) { 753 if (!miss->is_unused()) {
758 Label success; 754 Label success;
759 __ jmp(&success); 755 __ jmp(&success);
760 GenerateRestoreName(masm(), miss, name); 756 GenerateRestoreName(miss, name);
761 TailCallBuiltin(masm(), MissBuiltin(kind())); 757 TailCallBuiltin(masm(), MissBuiltin(kind()));
762 __ bind(&success); 758 __ bind(&success);
763 } 759 }
764 } 760 }
765 761
766 762
767 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg, 763 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
768 Handle<Name> name, 764 Handle<Name> name,
769 Handle<Object> callback) { 765 Handle<Object> callback) {
770 Label miss; 766 Label miss;
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 // Do tail-call to the runtime system. 1041 // Do tail-call to the runtime system.
1046 ExternalReference store_ic_property = ExternalReference( 1042 ExternalReference store_ic_property = ExternalReference(
1047 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 1043 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
1048 __ TailCallExternalReference(store_ic_property, 3, 1); 1044 __ TailCallExternalReference(store_ic_property, 3, 1);
1049 1045
1050 // Return the generated code. 1046 // Return the generated code.
1051 return GetCode(kind(), Code::FAST, name); 1047 return GetCode(kind(), Code::FAST, name);
1052 } 1048 }
1053 1049
1054 1050
1055 void NamedStoreHandlerCompiler::GenerateStoreArrayLength() {
1056 // Prepare tail call to StoreIC_ArrayLength.
1057 __ PopReturnAddressTo(scratch1());
1058 __ Push(receiver());
1059 __ Push(value());
1060 __ PushReturnAddressFrom(scratch1());
1061
1062 ExternalReference ref =
1063 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength),
1064 masm()->isolate());
1065 __ TailCallExternalReference(ref, 2, 1);
1066 }
1067
1068
1069 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( 1051 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
1070 MapHandleList* receiver_maps, CodeHandleList* handler_stubs, 1052 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
1071 MapHandleList* transitioned_maps) { 1053 MapHandleList* transitioned_maps) {
1072 Label miss; 1054 Label miss;
1073 __ JumpIfSmi(receiver(), &miss, Label::kNear); 1055 __ JumpIfSmi(receiver(), &miss, Label::kNear);
1074 1056
1075 __ movp(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); 1057 __ movp(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
1076 int receiver_count = receiver_maps->length(); 1058 int receiver_count = receiver_maps->length();
1077 for (int i = 0; i < receiver_count; ++i) { 1059 for (int i = 0; i < receiver_count; ++i) {
1078 // Check map and tail call if there's a match 1060 // Check map and tail call if there's a match
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 // ----------------------------------- 1302 // -----------------------------------
1321 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1303 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1322 } 1304 }
1323 1305
1324 1306
1325 #undef __ 1307 #undef __
1326 1308
1327 } } // namespace v8::internal 1309 } } // namespace v8::internal
1328 1310
1329 #endif // V8_TARGET_ARCH_X64 1311 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/stub-cache.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698