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

Side by Side Diff: src/runtime.cc

Issue 574753002: Don't use OwnPrototypeChainLength in GetOwnPropertyNames (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix Created 6 years, 3 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/objects.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 <stdlib.h> 5 #include <stdlib.h>
6 #include <limits> 6 #include <limits>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 5726 matching lines...) Expand 10 before | Expand all | Expand 10 after
5737 isolate, content, 5737 isolate, content,
5738 JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS)); 5738 JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
5739 5739
5740 // Test again, since cache may have been built by preceding call. 5740 // Test again, since cache may have been built by preceding call.
5741 if (object->IsSimpleEnum()) return object->map(); 5741 if (object->IsSimpleEnum()) return object->map();
5742 5742
5743 return *content; 5743 return *content;
5744 } 5744 }
5745 5745
5746 5746
5747 // Find the length of the prototype chain that is to be handled as one. If a
5748 // prototype object is hidden it is to be viewed as part of the the object it
5749 // is prototype for.
5750 static int OwnPrototypeChainLength(JSObject* obj) {
5751 int count = 1;
5752 for (PrototypeIterator iter(obj->GetIsolate(), obj);
5753 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
5754 count++;
5755 }
5756 return count;
5757 }
5758
5759
5760 // Return the names of the own named properties. 5747 // Return the names of the own named properties.
5761 // args[0]: object 5748 // args[0]: object
5762 // args[1]: PropertyAttributes as int 5749 // args[1]: PropertyAttributes as int
5763 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { 5750 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
5764 HandleScope scope(isolate); 5751 HandleScope scope(isolate);
5765 DCHECK(args.length() == 2); 5752 DCHECK(args.length() == 2);
5766 if (!args[0]->IsJSObject()) { 5753 if (!args[0]->IsJSObject()) {
5767 return isolate->heap()->undefined_value(); 5754 return isolate->heap()->undefined_value();
5768 } 5755 }
5769 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 5756 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5770 CONVERT_SMI_ARG_CHECKED(filter_value, 1); 5757 CONVERT_SMI_ARG_CHECKED(filter_value, 1);
5771 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); 5758 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
5772 5759
5773 // Skip the global proxy as it has no properties and always delegates to the
5774 // real global object.
5775 if (obj->IsJSGlobalProxy()) {
5776 // Only collect names if access is permitted.
5777 if (obj->IsAccessCheckNeeded() &&
5778 !isolate->MayNamedAccess(
5779 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5780 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
5781 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5782 return *isolate->factory()->NewJSArray(0);
5783 }
5784 PrototypeIterator iter(isolate, obj);
5785 obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
5786 }
5787
5788 // Find the number of objects making up this.
5789 int length = OwnPrototypeChainLength(*obj);
5790
5791 // Find the number of own properties for each of the objects. 5760 // Find the number of own properties for each of the objects.
5792 ScopedVector<int> own_property_count(length);
5793 int total_property_count = 0; 5761 int total_property_count = 0;
5794 { 5762 {
5795 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); 5763 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
5796 for (int i = 0; i < length; i++) { 5764 for (; !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN);
5765 iter.Advance()) {
5797 DCHECK(!iter.IsAtEnd()); 5766 DCHECK(!iter.IsAtEnd());
5798 Handle<JSObject> jsproto = 5767 Handle<JSObject> jsproto =
5799 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 5768 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
5800 // Only collect names if access is permitted. 5769 // Only collect names if access is permitted.
5801 if (jsproto->IsAccessCheckNeeded() && 5770 if (jsproto->IsAccessCheckNeeded() &&
5802 !isolate->MayNamedAccess(jsproto, 5771 !isolate->MayNamedAccess(jsproto,
5803 isolate->factory()->undefined_value(), 5772 isolate->factory()->undefined_value(),
5804 v8::ACCESS_KEYS)) { 5773 v8::ACCESS_KEYS)) {
5805 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS); 5774 isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
5806 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 5775 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5807 return *isolate->factory()->NewJSArray(0); 5776 return *isolate->factory()->NewJSArray(0);
5808 } 5777 }
5809 int n; 5778 int n;
5810 n = jsproto->NumberOfOwnProperties(filter); 5779 n = jsproto->NumberOfOwnProperties(filter);
5811 own_property_count[i] = n;
5812 total_property_count += n; 5780 total_property_count += n;
5813 iter.Advance();
5814 } 5781 }
5815 } 5782 }
5816 5783
5817 // Allocate an array with storage for all the property names. 5784 // Allocate an array with storage for all the property names.
5818 Handle<FixedArray> names = 5785 Handle<FixedArray> names =
5819 isolate->factory()->NewFixedArray(total_property_count); 5786 isolate->factory()->NewFixedArray(total_property_count);
5820 5787
5821 // Get the property names. 5788 // Get the property names.
5822 int next_copy_index = 0; 5789 int next_copy_index = 0;
5823 int hidden_strings = 0; 5790 int hidden_strings = 0;
5824 { 5791 {
5825 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); 5792 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
5826 for (int i = 0; i < length; i++) { 5793 for (; !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN);
5827 DCHECK(!iter.IsAtEnd()); 5794 iter.Advance()) {
5828 Handle<JSObject> jsproto = 5795 Handle<JSObject> jsproto =
5829 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 5796 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
5830 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); 5797 int own_property_count =
5831 if (i > 0) { 5798 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
5799 if (!jsproto.is_identical_to(obj)) {
5832 // Names from hidden prototypes may already have been added 5800 // Names from hidden prototypes may already have been added
5833 // for inherited function template instances. Count the duplicates 5801 // for inherited function template instances. Count the duplicates
5834 // and stub them out; the final copy pass at the end ignores holes. 5802 // and stub them out; the final copy pass at the end ignores holes.
5835 for (int j = next_copy_index; 5803 for (int j = next_copy_index; j < next_copy_index + own_property_count;
5836 j < next_copy_index + own_property_count[i]; j++) { 5804 j++) {
5837 Object* name_from_hidden_proto = names->get(j); 5805 Object* name_from_hidden_proto = names->get(j);
5838 for (int k = 0; k < next_copy_index; k++) { 5806 for (int k = 0; k < next_copy_index; k++) {
5839 if (names->get(k) != isolate->heap()->hidden_string()) { 5807 if (names->get(k) != isolate->heap()->hidden_string()) {
5840 Object* name = names->get(k); 5808 Object* name = names->get(k);
5841 if (name_from_hidden_proto == name) { 5809 if (name_from_hidden_proto == name) {
5842 names->set(j, isolate->heap()->hidden_string()); 5810 names->set(j, isolate->heap()->hidden_string());
5843 hidden_strings++; 5811 hidden_strings++;
5844 break; 5812 break;
5845 } 5813 }
5846 } 5814 }
5847 } 5815 }
5848 } 5816 }
5849 } 5817 }
5850 next_copy_index += own_property_count[i]; 5818 next_copy_index += own_property_count;
5851 5819
5852 // Hidden properties only show up if the filter does not skip strings. 5820 // Hidden properties only show up if the filter does not skip strings.
5853 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { 5821 if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
5854 hidden_strings++; 5822 hidden_strings++;
5855 } 5823 }
5856 iter.Advance();
5857 } 5824 }
5858 } 5825 }
5859 5826
5860 // Filter out name of hidden properties object and 5827 // Filter out name of hidden properties object and
5861 // hidden prototype duplicates. 5828 // hidden prototype duplicates.
5862 if (hidden_strings > 0) { 5829 if (hidden_strings > 0) {
5863 Handle<FixedArray> old_names = names; 5830 Handle<FixedArray> old_names = names;
5864 names = isolate->factory()->NewFixedArray( 5831 names = isolate->factory()->NewFixedArray(
5865 names->length() - hidden_strings); 5832 names->length() - hidden_strings);
5866 int dest_pos = 0; 5833 int dest_pos = 0;
(...skipping 9813 matching lines...) Expand 10 before | Expand all | Expand 10 after
15680 } 15647 }
15681 return NULL; 15648 return NULL;
15682 } 15649 }
15683 15650
15684 15651
15685 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 15652 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
15686 return &(kIntrinsicFunctions[static_cast<int>(id)]); 15653 return &(kIntrinsicFunctions[static_cast<int>(id)]);
15687 } 15654 }
15688 15655
15689 } } // namespace v8::internal 15656 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698