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

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

Issue 6894003: Better support for 'polymorphic' JS and external arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: new strategy Created 9 years, 7 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
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 Object* result; 450 Object* result;
451 { MaybeObject* maybe_result = 451 { MaybeObject* maybe_result =
452 receiver->UpdateMapCodeCache(name, Code::cast(code)); 452 receiver->UpdateMapCodeCache(name, Code::cast(code));
453 if (!maybe_result->ToObject(&result)) return maybe_result; 453 if (!maybe_result->ToObject(&result)) return maybe_result;
454 } 454 }
455 } 455 }
456 return code; 456 return code;
457 } 457 }
458 458
459 459
460 MaybeObject* StubCache::ComputeKeyedLoadSpecialized(JSObject* receiver) {
461 // Using NORMAL as the PropertyType for array element loads is a misuse. The
462 // generated stub always accesses fast elements, not slow-mode fields, but
463 // some property type is required for the stub lookup. Note that overloading
464 // the NORMAL PropertyType is only safe as long as no stubs are generated for
465 // other keyed field loads. This is guaranteed to be the case since all field
466 // keyed loads that are not array elements go through a generic builtin stub.
467 Code::Flags flags =
468 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, NORMAL);
469 String* name = heap()->KeyedLoadSpecialized_symbol();
470 Object* code = receiver->map()->FindInCodeCache(name, flags);
471 if (code->IsUndefined()) {
472 KeyedLoadStubCompiler compiler;
473 { MaybeObject* maybe_code = compiler.CompileLoadSpecialized(receiver);
474 if (!maybe_code->ToObject(&code)) return maybe_code;
475 }
476 PROFILE(isolate_,
477 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), 0));
478 Object* result;
479 { MaybeObject* maybe_result =
480 receiver->UpdateMapCodeCache(name, Code::cast(code));
481 if (!maybe_result->ToObject(&result)) return maybe_result;
482 }
483 }
484 return code;
485 }
486
487
488 MaybeObject* StubCache::ComputeStoreField(String* name, 460 MaybeObject* StubCache::ComputeStoreField(String* name,
489 JSObject* receiver, 461 JSObject* receiver,
490 int field_index, 462 int field_index,
491 Map* transition, 463 Map* transition,
492 StrictModeFlag strict_mode) { 464 StrictModeFlag strict_mode) {
493 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; 465 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION;
494 Code::Flags flags = Code::ComputeMonomorphicFlags( 466 Code::Flags flags = Code::ComputeMonomorphicFlags(
495 Code::STORE_IC, type, strict_mode); 467 Code::STORE_IC, type, strict_mode);
496 Object* code = receiver->map()->FindInCodeCache(name, flags); 468 Object* code = receiver->map()->FindInCodeCache(name, flags);
497 if (code->IsUndefined()) { 469 if (code->IsUndefined()) {
498 StoreStubCompiler compiler(strict_mode); 470 StoreStubCompiler compiler(strict_mode);
499 { MaybeObject* maybe_code = 471 { MaybeObject* maybe_code =
500 compiler.CompileStoreField(receiver, field_index, transition, name); 472 compiler.CompileStoreField(receiver, field_index, transition, name);
501 if (!maybe_code->ToObject(&code)) return maybe_code; 473 if (!maybe_code->ToObject(&code)) return maybe_code;
502 } 474 }
503 PROFILE(isolate_, 475 PROFILE(isolate_,
504 CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); 476 CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
505 GDBJIT(AddCode(GDBJITInterface::STORE_IC, name, Code::cast(code))); 477 GDBJIT(AddCode(GDBJITInterface::STORE_IC, name, Code::cast(code)));
506 Object* result; 478 Object* result;
507 { MaybeObject* maybe_result = 479 { MaybeObject* maybe_result =
508 receiver->UpdateMapCodeCache(name, Code::cast(code)); 480 receiver->UpdateMapCodeCache(name, Code::cast(code));
509 if (!maybe_result->ToObject(&result)) return maybe_result; 481 if (!maybe_result->ToObject(&result)) return maybe_result;
510 } 482 }
511 } 483 }
512 return code; 484 return code;
513 } 485 }
514 486
515 487
516 MaybeObject* StubCache::ComputeKeyedStoreSpecialized(
517 JSObject* receiver,
518 StrictModeFlag strict_mode) {
519 Code::Flags flags =
520 Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, NORMAL, strict_mode);
521 String* name = heap()->KeyedStoreSpecialized_symbol();
522 Object* code = receiver->map()->FindInCodeCache(name, flags);
523 if (code->IsUndefined()) {
524 KeyedStoreStubCompiler compiler(strict_mode);
525 { MaybeObject* maybe_code = compiler.CompileStoreSpecialized(receiver);
526 if (!maybe_code->ToObject(&code)) return maybe_code;
527 }
528 PROFILE(isolate_,
529 CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, Code::cast(code), 0));
530 Object* result;
531 { MaybeObject* maybe_result =
532 receiver->UpdateMapCodeCache(name, Code::cast(code));
533 if (!maybe_result->ToObject(&result)) return maybe_result;
534 }
535 }
536 return code;
537 }
538
539
540 namespace { 488 namespace {
541 489
542 ExternalArrayType ElementsKindToExternalArrayType(JSObject::ElementsKind kind) { 490 ExternalArrayType ElementsKindToExternalArrayType(JSObject::ElementsKind kind) {
543 switch (kind) { 491 switch (kind) {
544 case JSObject::EXTERNAL_BYTE_ELEMENTS: 492 case JSObject::EXTERNAL_BYTE_ELEMENTS:
545 return kExternalByteArray; 493 return kExternalByteArray;
546 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 494 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
547 return kExternalUnsignedByteArray; 495 return kExternalUnsignedByteArray;
548 case JSObject::EXTERNAL_SHORT_ELEMENTS: 496 case JSObject::EXTERNAL_SHORT_ELEMENTS:
549 return kExternalShortArray; 497 return kExternalShortArray;
550 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 498 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
551 return kExternalUnsignedShortArray; 499 return kExternalUnsignedShortArray;
552 case JSObject::EXTERNAL_INT_ELEMENTS: 500 case JSObject::EXTERNAL_INT_ELEMENTS:
553 return kExternalIntArray; 501 return kExternalIntArray;
554 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: 502 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
555 return kExternalUnsignedIntArray; 503 return kExternalUnsignedIntArray;
556 case JSObject::EXTERNAL_FLOAT_ELEMENTS: 504 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
557 return kExternalFloatArray; 505 return kExternalFloatArray;
558 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: 506 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
559 return kExternalDoubleArray; 507 return kExternalDoubleArray;
560 case JSObject::EXTERNAL_PIXEL_ELEMENTS: 508 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
561 return kExternalPixelArray; 509 return kExternalPixelArray;
562 default: 510 default:
563 UNREACHABLE(); 511 UNREACHABLE();
564 return static_cast<ExternalArrayType>(0); 512 return static_cast<ExternalArrayType>(0);
565 } 513 }
566 } 514 }
567 515
568 String* ExternalArrayTypeToStubName(Heap* heap,
569 ExternalArrayType array_type,
570 bool is_store) {
571 if (is_store) {
572 switch (array_type) {
573 case kExternalByteArray:
574 return heap->KeyedStoreExternalByteArray_symbol();
575 case kExternalUnsignedByteArray:
576 return heap->KeyedStoreExternalUnsignedByteArray_symbol();
577 case kExternalShortArray:
578 return heap->KeyedStoreExternalShortArray_symbol();
579 case kExternalUnsignedShortArray:
580 return heap->KeyedStoreExternalUnsignedShortArray_symbol();
581 case kExternalIntArray:
582 return heap->KeyedStoreExternalIntArray_symbol();
583 case kExternalUnsignedIntArray:
584 return heap->KeyedStoreExternalUnsignedIntArray_symbol();
585 case kExternalFloatArray:
586 return heap->KeyedStoreExternalFloatArray_symbol();
587 case kExternalDoubleArray:
588 return heap->KeyedStoreExternalDoubleArray_symbol();
589 case kExternalPixelArray:
590 return heap->KeyedStoreExternalPixelArray_symbol();
591 default:
592 UNREACHABLE();
593 return NULL;
594 }
595 } else {
596 switch (array_type) {
597 case kExternalByteArray:
598 return heap->KeyedLoadExternalByteArray_symbol();
599 case kExternalUnsignedByteArray:
600 return heap->KeyedLoadExternalUnsignedByteArray_symbol();
601 case kExternalShortArray:
602 return heap->KeyedLoadExternalShortArray_symbol();
603 case kExternalUnsignedShortArray:
604 return heap->KeyedLoadExternalUnsignedShortArray_symbol();
605 case kExternalIntArray:
606 return heap->KeyedLoadExternalIntArray_symbol();
607 case kExternalUnsignedIntArray:
608 return heap->KeyedLoadExternalUnsignedIntArray_symbol();
609 case kExternalFloatArray:
610 return heap->KeyedLoadExternalFloatArray_symbol();
611 case kExternalDoubleArray:
612 return heap->KeyedLoadExternalDoubleArray_symbol();
613 case kExternalPixelArray:
614 return heap->KeyedLoadExternalPixelArray_symbol();
615 default:
616 UNREACHABLE();
617 return NULL;
618 }
619 }
620 }
621
622 } // anonymous namespace 516 } // anonymous namespace
623 517
624 518
625 MaybeObject* StubCache::ComputeKeyedLoadOrStoreExternalArray( 519 MaybeObject* StubCache::ComputeKeyedLoadOrStoreExternalArray(
626 JSObject* receiver, 520 JSObject* receiver,
627 bool is_store, 521 bool is_store,
628 StrictModeFlag strict_mode) { 522 StrictModeFlag strict_mode) {
629 Code::Flags flags = 523 Code::Flags flags =
630 Code::ComputeMonomorphicFlags( 524 Code::ComputeMonomorphicFlags(
631 is_store ? Code::KEYED_EXTERNAL_ARRAY_STORE_IC : 525 is_store ? Code::KEYED_STORE_IC :
632 Code::KEYED_EXTERNAL_ARRAY_LOAD_IC, 526 Code::KEYED_LOAD_IC,
633 NORMAL, 527 NORMAL,
634 strict_mode); 528 strict_mode);
635 ExternalArrayType array_type = 529 ExternalArrayType array_type =
636 ElementsKindToExternalArrayType(receiver->GetElementsKind()); 530 ElementsKindToExternalArrayType(receiver->GetElementsKind());
637 String* name = ExternalArrayTypeToStubName(heap(), array_type, is_store); 531 String* name = is_store
532 ? isolate()->heap()->KeyedStoreSpecializedMonomorphic_symbol()
533 : isolate()->heap()->KeyedLoadSpecializedMonomorphic_symbol();
638 Object* code = receiver->map()->FindInCodeCache(name, flags); 534 Object* code = receiver->map()->FindInCodeCache(name, flags);
639 if (code->IsUndefined()) { 535 if (code->IsUndefined()) {
640 ExternalArrayStubCompiler compiler; 536 ExternalArrayStubCompiler compiler;
641 { MaybeObject* maybe_code = 537 { MaybeObject* maybe_code =
642 is_store ? 538 is_store ?
643 compiler.CompileKeyedStoreStub(receiver, array_type, flags) : 539 compiler.CompileKeyedStoreStub(receiver, array_type, flags) :
644 compiler.CompileKeyedLoadStub(receiver, array_type, flags); 540 compiler.CompileKeyedLoadStub(receiver, array_type, flags);
645 if (!maybe_code->ToObject(&code)) return maybe_code; 541 if (!maybe_code->ToObject(&code)) return maybe_code;
646 } 542 }
647 Code::cast(code)->set_external_array_type(array_type); 543 Code::cast(code)->set_external_array_type(array_type);
648 if (is_store) { 544 if (is_store) {
649 PROFILE(isolate_, 545 PROFILE(isolate_,
650 CodeCreateEvent(Logger::KEYED_EXTERNAL_ARRAY_STORE_IC_TAG, 546 CodeCreateEvent(Logger::KEYED_EXTERNAL_ARRAY_STORE_IC_TAG,
651 Code::cast(code), 0)); 547 Code::cast(code), 0));
652 } else { 548 } else {
653 PROFILE(isolate_, 549 PROFILE(isolate_,
654 CodeCreateEvent(Logger::KEYED_EXTERNAL_ARRAY_LOAD_IC_TAG, 550 CodeCreateEvent(Logger::KEYED_EXTERNAL_ARRAY_LOAD_IC_TAG,
655 Code::cast(code), 0)); 551 Code::cast(code), 0));
656 } 552 }
553 ASSERT(code->IsCode());
657 Object* result; 554 Object* result;
658 { MaybeObject* maybe_result = 555 { MaybeObject* maybe_result =
659 receiver->UpdateMapCodeCache(name, Code::cast(code)); 556 receiver->UpdateMapCodeCache(name, Code::cast(code));
660 if (!maybe_result->ToObject(&result)) return maybe_result; 557 if (!maybe_result->ToObject(&result)) return maybe_result;
661 } 558 }
662 } 559 }
663 return code; 560 return code;
664 } 561 }
665 562
666 563
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 Code::cast(result->ToObjectUnchecked()), 1607 Code::cast(result->ToObjectUnchecked()),
1711 name)); 1608 name));
1712 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, 1609 GDBJIT(AddCode(GDBJITInterface::LOAD_IC,
1713 name, 1610 name,
1714 Code::cast(result->ToObjectUnchecked()))); 1611 Code::cast(result->ToObjectUnchecked())));
1715 } 1612 }
1716 return result; 1613 return result;
1717 } 1614 }
1718 1615
1719 1616
1720 MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type, String* name) { 1617 MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type,
1721 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, type); 1618 String* name,
1619 InlineCacheState state) {
1620 Code::Flags flags = Code::ComputeFlags(
1621 Code::KEYED_LOAD_IC, NOT_IN_LOOP, state, Code::kNoExtraICState, type);
1722 MaybeObject* result = GetCodeWithFlags(flags, name); 1622 MaybeObject* result = GetCodeWithFlags(flags, name);
1723 if (!result->IsFailure()) { 1623 if (!result->IsFailure()) {
1724 PROFILE(isolate(), 1624 PROFILE(isolate(),
1725 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, 1625 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG,
1726 Code::cast(result->ToObjectUnchecked()), 1626 Code::cast(result->ToObjectUnchecked()),
1727 name)); 1627 name));
1728 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, 1628 GDBJIT(AddCode(GDBJITInterface::LOAD_IC,
1729 name, 1629 name,
1730 Code::cast(result->ToObjectUnchecked()))); 1630 Code::cast(result->ToObjectUnchecked())));
1731 } 1631 }
(...skipping 11 matching lines...) Expand all
1743 Code::cast(result->ToObjectUnchecked()), 1643 Code::cast(result->ToObjectUnchecked()),
1744 name)); 1644 name));
1745 GDBJIT(AddCode(GDBJITInterface::STORE_IC, 1645 GDBJIT(AddCode(GDBJITInterface::STORE_IC,
1746 name, 1646 name,
1747 Code::cast(result->ToObjectUnchecked()))); 1647 Code::cast(result->ToObjectUnchecked())));
1748 } 1648 }
1749 return result; 1649 return result;
1750 } 1650 }
1751 1651
1752 1652
1753 MaybeObject* KeyedStoreStubCompiler::GetCode(PropertyType type, String* name) { 1653 MaybeObject* KeyedStoreStubCompiler::GetCode(PropertyType type,
1754 Code::Flags flags = Code::ComputeMonomorphicFlags( 1654 String* name,
1755 Code::KEYED_STORE_IC, type, strict_mode_); 1655 InlineCacheState state) {
1656 Code::Flags flags = Code::ComputeFlags(
1657 Code::KEYED_STORE_IC, NOT_IN_LOOP, state, strict_mode_, type);
1756 MaybeObject* result = GetCodeWithFlags(flags, name); 1658 MaybeObject* result = GetCodeWithFlags(flags, name);
1757 if (!result->IsFailure()) { 1659 if (!result->IsFailure()) {
1758 PROFILE(isolate(), 1660 PROFILE(isolate(),
1759 CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, 1661 CodeCreateEvent(Logger::KEYED_STORE_IC_TAG,
1760 Code::cast(result->ToObjectUnchecked()), 1662 Code::cast(result->ToObjectUnchecked()),
1761 name)); 1663 name));
1762 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, 1664 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC,
1763 name, 1665 name,
1764 Code::cast(result->ToObjectUnchecked()))); 1666 Code::cast(result->ToObjectUnchecked())));
1765 } 1667 }
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1937 } 1839 }
1938 Code* code = Code::cast(result); 1840 Code* code = Code::cast(result);
1939 USE(code); 1841 USE(code);
1940 PROFILE(isolate(), 1842 PROFILE(isolate(),
1941 CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayStub")); 1843 CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayStub"));
1942 return result; 1844 return result;
1943 } 1845 }
1944 1846
1945 1847
1946 } } // namespace v8::internal 1848 } } // namespace v8::internal
OLDNEW
« src/ic.cc ('K') | « src/stub-cache.h ('k') | src/type-info.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698