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

Side by Side Diff: src/objects.cc

Issue 25025002: Use a walking visitor to traverse JSObject structure. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Missed a spot! Created 7 years, 2 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 | « no previous file | test/mjsunit/big-array-literal.js » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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
(...skipping 5565 matching lines...) Expand 10 before | Expand all | Expand 10 after
5576 } 5576 }
5577 5577
5578 5578
5579 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { 5579 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
5580 Isolate* isolate = object->GetIsolate(); 5580 Isolate* isolate = object->GetIsolate();
5581 CALL_HEAP_FUNCTION(isolate, 5581 CALL_HEAP_FUNCTION(isolate,
5582 isolate->heap()->CopyJSObject(*object), JSObject); 5582 isolate->heap()->CopyJSObject(*object), JSObject);
5583 } 5583 }
5584 5584
5585 5585
5586 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) { 5586 class JSObjectWalkVisitor {
5587 public:
5588 explicit JSObjectWalkVisitor() {}
5589 virtual ~JSObjectWalkVisitor() {}
5590
5591 Handle<JSObject> Visit(Handle<JSObject> object) {
5592 return StructureWalk(object);
5593 }
5594
5595 // Returns true if the visitor is a copying visitor.
5596 virtual bool is_copying() = 0;
5597
5598 protected:
5599 Handle<JSObject> StructureWalk(Handle<JSObject> object);
5600
5601 // The returned handle should point to a new object if the visitor is a
5602 // copying visitor, otherwise it should be the same as the input object.
5603 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0;
5604
5605 // The returned handle should point to a new value if the visitor is a
5606 // copying visitor, otherwise it should be the same as the input value.
5607 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object,
5608 Handle<JSObject> value) = 0;
5609 };
5610
5611
5612 class JSObjectCopyVisitor: public JSObjectWalkVisitor {
5613 public:
5614 explicit JSObjectCopyVisitor() {}
5615
5616 virtual bool is_copying() V8_OVERRIDE { return true; }
5617
5618 protected:
5619 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
5620 return JSObject::Copy(object);
5621 }
5622
5623 virtual Handle<JSObject> VisitElementOrProperty(
5624 Handle<JSObject> object,
5625 Handle<JSObject> value) V8_OVERRIDE {
5626 return StructureWalk(value);
5627 }
5628 };
5629
5630
5631 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) {
5632 bool copying = is_copying();
5587 Isolate* isolate = object->GetIsolate(); 5633 Isolate* isolate = object->GetIsolate();
5588 StackLimitCheck check(isolate); 5634 StackLimitCheck check(isolate);
5589 if (check.HasOverflowed()) { 5635 if (check.HasOverflowed()) {
5590 isolate->StackOverflow(); 5636 isolate->StackOverflow();
5591 return Handle<JSObject>::null(); 5637 return Handle<JSObject>::null();
5592 } 5638 }
5593 5639
5594 if (object->map()->is_deprecated()) { 5640 if (object->map()->is_deprecated()) {
5595 MigrateInstance(object); 5641 JSObject::MigrateInstance(object);
5596 } 5642 }
5597 5643
5598 Handle<JSObject> copy = Copy(object); 5644 Handle<JSObject> copy = VisitObject(object);
5645 ASSERT(copying || copy.is_identical_to(object));
5599 5646
5600 HandleScope scope(isolate); 5647 HandleScope scope(isolate);
5601 5648
5602 // Deep copy local properties. 5649 // Deep copy local properties.
5603 if (copy->HasFastProperties()) { 5650 if (copy->HasFastProperties()) {
5604 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); 5651 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
5605 int limit = copy->map()->NumberOfOwnDescriptors(); 5652 int limit = copy->map()->NumberOfOwnDescriptors();
5606 for (int i = 0; i < limit; i++) { 5653 for (int i = 0; i < limit; i++) {
5607 PropertyDetails details = descriptors->GetDetails(i); 5654 PropertyDetails details = descriptors->GetDetails(i);
5608 if (details.type() != FIELD) continue; 5655 if (details.type() != FIELD) continue;
5609 int index = descriptors->GetFieldIndex(i); 5656 int index = descriptors->GetFieldIndex(i);
5610 Handle<Object> value(object->RawFastPropertyAt(index), isolate); 5657 Handle<Object> value(object->RawFastPropertyAt(index), isolate);
5611 if (value->IsJSObject()) { 5658 if (value->IsJSObject()) {
5612 value = DeepCopy(Handle<JSObject>::cast(value)); 5659 value = VisitElementOrProperty(copy, Handle<JSObject>::cast(value));
5613 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>()); 5660 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>());
5614 } else { 5661 } else {
5615 Representation representation = details.representation(); 5662 Representation representation = details.representation();
5616 value = NewStorageFor(isolate, value, representation); 5663 value = NewStorageFor(isolate, value, representation);
5617 } 5664 }
5618 copy->FastPropertyAtPut(index, *value); 5665 if (copying) {
5666 copy->FastPropertyAtPut(index, *value);
5667 }
5619 } 5668 }
5620 } else { 5669 } else {
5621 Handle<FixedArray> names = 5670 Handle<FixedArray> names =
5622 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); 5671 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties());
5623 copy->GetLocalPropertyNames(*names, 0); 5672 copy->GetLocalPropertyNames(*names, 0);
5624 for (int i = 0; i < names->length(); i++) { 5673 for (int i = 0; i < names->length(); i++) {
5625 ASSERT(names->get(i)->IsString()); 5674 ASSERT(names->get(i)->IsString());
5626 Handle<String> key_string(String::cast(names->get(i))); 5675 Handle<String> key_string(String::cast(names->get(i)));
5627 PropertyAttributes attributes = 5676 PropertyAttributes attributes =
5628 copy->GetLocalPropertyAttribute(*key_string); 5677 copy->GetLocalPropertyAttribute(*key_string);
5629 // Only deep copy fields from the object literal expression. 5678 // Only deep copy fields from the object literal expression.
5630 // In particular, don't try to copy the length attribute of 5679 // In particular, don't try to copy the length attribute of
5631 // an array. 5680 // an array.
5632 if (attributes != NONE) continue; 5681 if (attributes != NONE) continue;
5633 Handle<Object> value( 5682 Handle<Object> value(
5634 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), 5683 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(),
5635 isolate); 5684 isolate);
5636 if (value->IsJSObject()) { 5685 if (value->IsJSObject()) {
5637 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); 5686 Handle<JSObject> result = VisitElementOrProperty(
5687 copy, Handle<JSObject>::cast(value));
5638 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); 5688 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
5639 // Creating object copy for literals. No strict mode needed. 5689 if (copying) {
5640 CHECK_NOT_EMPTY_HANDLE(isolate, SetProperty( 5690 // Creating object copy for literals. No strict mode needed.
5641 copy, key_string, result, NONE, kNonStrictMode)); 5691 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty(
5692 copy, key_string, result, NONE, kNonStrictMode));
5693 }
5642 } 5694 }
5643 } 5695 }
5644 } 5696 }
5645 5697
5646 // Deep copy local elements. 5698 // Deep copy local elements.
5647 // Pixel elements cannot be created using an object literal. 5699 // Pixel elements cannot be created using an object literal.
5648 ASSERT(!copy->HasExternalArrayElements()); 5700 ASSERT(!copy->HasExternalArrayElements());
5649 switch (copy->GetElementsKind()) { 5701 switch (copy->GetElementsKind()) {
5650 case FAST_SMI_ELEMENTS: 5702 case FAST_SMI_ELEMENTS:
5651 case FAST_ELEMENTS: 5703 case FAST_ELEMENTS:
5652 case FAST_HOLEY_SMI_ELEMENTS: 5704 case FAST_HOLEY_SMI_ELEMENTS:
5653 case FAST_HOLEY_ELEMENTS: { 5705 case FAST_HOLEY_ELEMENTS: {
5654 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); 5706 Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
5655 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { 5707 if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
5656 isolate->counters()->cow_arrays_created_runtime()->Increment(); 5708 isolate->counters()->cow_arrays_created_runtime()->Increment();
5657 #ifdef DEBUG 5709 #ifdef DEBUG
5658 for (int i = 0; i < elements->length(); i++) { 5710 for (int i = 0; i < elements->length(); i++) {
5659 ASSERT(!elements->get(i)->IsJSObject()); 5711 ASSERT(!elements->get(i)->IsJSObject());
5660 } 5712 }
5661 #endif 5713 #endif
5662 } else { 5714 } else {
5663 for (int i = 0; i < elements->length(); i++) { 5715 for (int i = 0; i < elements->length(); i++) {
5664 Handle<Object> value(elements->get(i), isolate); 5716 Handle<Object> value(elements->get(i), isolate);
5665 ASSERT(value->IsSmi() || 5717 ASSERT(value->IsSmi() ||
5666 value->IsTheHole() || 5718 value->IsTheHole() ||
5667 (IsFastObjectElementsKind(copy->GetElementsKind()))); 5719 (IsFastObjectElementsKind(copy->GetElementsKind())));
5668 if (value->IsJSObject()) { 5720 if (value->IsJSObject()) {
5669 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); 5721 Handle<JSObject> result = VisitElementOrProperty(
5722 copy, Handle<JSObject>::cast(value));
5670 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); 5723 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
5671 elements->set(i, *result); 5724 if (copying) {
5725 elements->set(i, *result);
5726 }
5672 } 5727 }
5673 } 5728 }
5674 } 5729 }
5675 break; 5730 break;
5676 } 5731 }
5677 case DICTIONARY_ELEMENTS: { 5732 case DICTIONARY_ELEMENTS: {
5678 Handle<SeededNumberDictionary> element_dictionary( 5733 Handle<SeededNumberDictionary> element_dictionary(
5679 copy->element_dictionary()); 5734 copy->element_dictionary());
5680 int capacity = element_dictionary->Capacity(); 5735 int capacity = element_dictionary->Capacity();
5681 for (int i = 0; i < capacity; i++) { 5736 for (int i = 0; i < capacity; i++) {
5682 Object* k = element_dictionary->KeyAt(i); 5737 Object* k = element_dictionary->KeyAt(i);
5683 if (element_dictionary->IsKey(k)) { 5738 if (element_dictionary->IsKey(k)) {
5684 Handle<Object> value(element_dictionary->ValueAt(i), isolate); 5739 Handle<Object> value(element_dictionary->ValueAt(i), isolate);
5685 if (value->IsJSObject()) { 5740 if (value->IsJSObject()) {
5686 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); 5741 Handle<JSObject> result = VisitElementOrProperty(
5742 copy, Handle<JSObject>::cast(value));
5687 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); 5743 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
5688 element_dictionary->ValueAtPut(i, *result); 5744 if (copying) {
5745 element_dictionary->ValueAtPut(i, *result);
5746 }
5689 } 5747 }
5690 } 5748 }
5691 } 5749 }
5692 break; 5750 break;
5693 } 5751 }
5694 case NON_STRICT_ARGUMENTS_ELEMENTS: 5752 case NON_STRICT_ARGUMENTS_ELEMENTS:
5695 UNIMPLEMENTED(); 5753 UNIMPLEMENTED();
5696 break; 5754 break;
5697 case EXTERNAL_PIXEL_ELEMENTS: 5755 case EXTERNAL_PIXEL_ELEMENTS:
5698 case EXTERNAL_BYTE_ELEMENTS: 5756 case EXTERNAL_BYTE_ELEMENTS:
5699 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 5757 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
5700 case EXTERNAL_SHORT_ELEMENTS: 5758 case EXTERNAL_SHORT_ELEMENTS:
5701 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 5759 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
5702 case EXTERNAL_INT_ELEMENTS: 5760 case EXTERNAL_INT_ELEMENTS:
5703 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 5761 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
5704 case EXTERNAL_FLOAT_ELEMENTS: 5762 case EXTERNAL_FLOAT_ELEMENTS:
5705 case EXTERNAL_DOUBLE_ELEMENTS: 5763 case EXTERNAL_DOUBLE_ELEMENTS:
5706 case FAST_DOUBLE_ELEMENTS: 5764 case FAST_DOUBLE_ELEMENTS:
5707 case FAST_HOLEY_DOUBLE_ELEMENTS: 5765 case FAST_HOLEY_DOUBLE_ELEMENTS:
5708 // No contained objects, nothing to do. 5766 // No contained objects, nothing to do.
5709 break; 5767 break;
5710 } 5768 }
5711 return copy; 5769 return copy;
5712 } 5770 }
5713 5771
5714 5772
5773 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
5774 JSObjectCopyVisitor v;
5775 Handle<JSObject> copy = v.Visit(object);
5776 ASSERT(v.is_copying() && !copy.is_identical_to(object));
5777 return copy;
5778 }
5779
5780
5715 // Tests for the fast common case for property enumeration: 5781 // Tests for the fast common case for property enumeration:
5716 // - This object and all prototypes has an enum cache (which means that 5782 // - This object and all prototypes has an enum cache (which means that
5717 // it is no proxy, has no interceptors and needs no access checks). 5783 // it is no proxy, has no interceptors and needs no access checks).
5718 // - This object has no elements. 5784 // - This object has no elements.
5719 // - No prototype has enumerable properties/elements. 5785 // - No prototype has enumerable properties/elements.
5720 bool JSReceiver::IsSimpleEnum() { 5786 bool JSReceiver::IsSimpleEnum() {
5721 Heap* heap = GetHeap(); 5787 Heap* heap = GetHeap();
5722 for (Object* o = this; 5788 for (Object* o = this;
5723 o != heap->null_value(); 5789 o != heap->null_value();
5724 o = JSObject::cast(o)->GetPrototype()) { 5790 o = JSObject::cast(o)->GetPrototype()) {
(...skipping 10394 matching lines...) Expand 10 before | Expand all | Expand 10 after
16119 #define ERROR_MESSAGES_TEXTS(C, T) T, 16185 #define ERROR_MESSAGES_TEXTS(C, T) T,
16120 static const char* error_messages_[] = { 16186 static const char* error_messages_[] = {
16121 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16187 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16122 }; 16188 };
16123 #undef ERROR_MESSAGES_TEXTS 16189 #undef ERROR_MESSAGES_TEXTS
16124 return error_messages_[reason]; 16190 return error_messages_[reason];
16125 } 16191 }
16126 16192
16127 16193
16128 } } // namespace v8::internal 16194 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/big-array-literal.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698