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

Side by Side Diff: src/runtime.cc

Issue 18658: Added handling of hidden prototype objects when collecting local properties f... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 11 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/runtime.h ('k') | test/cctest/test-debug.cc » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 4518 matching lines...) Expand 10 before | Expand all | Expand 10 after
4529 } 4529 }
4530 4530
4531 4531
4532 static Object* Runtime_Break(Arguments args) { 4532 static Object* Runtime_Break(Arguments args) {
4533 ASSERT(args.length() == 0); 4533 ASSERT(args.length() == 0);
4534 StackGuard::DebugBreak(); 4534 StackGuard::DebugBreak();
4535 return Heap::undefined_value(); 4535 return Heap::undefined_value();
4536 } 4536 }
4537 4537
4538 4538
4539 // Find the length of the prototype chain that is to to handled as one. If a
4540 // prototype object is hidden it is to be viewed as part of the the object it
4541 // is prototype for.
4542 static int LocalPrototypeChainLength(JSObject* obj) {
4543 int count = 1;
4544 Object* proto = obj->GetPrototype();
4545 while (proto->IsJSObject() &&
4546 JSObject::cast(proto)->map()->is_hidden_prototype()) {
4547 count++;
4548 proto = JSObject::cast(proto)->GetPrototype();
4549 }
4550 return count;
4551 }
4552
4553
4539 static Object* DebugLookupResultValue(Object* receiver, LookupResult* result, 4554 static Object* DebugLookupResultValue(Object* receiver, LookupResult* result,
4540 bool* caught_exception) { 4555 bool* caught_exception) {
4541 Object* value; 4556 Object* value;
4542 switch (result->type()) { 4557 switch (result->type()) {
4543 case NORMAL: { 4558 case NORMAL: {
4544 Dictionary* dict = 4559 Dictionary* dict =
4545 JSObject::cast(result->holder())->property_dictionary(); 4560 JSObject::cast(result->holder())->property_dictionary();
4546 value = dict->ValueAt(result->GetDictionaryEntry()); 4561 value = dict->ValueAt(result->GetDictionaryEntry());
4547 if (value->IsTheHole()) { 4562 if (value->IsTheHole()) {
4548 return Heap::undefined_value(); 4563 return Heap::undefined_value();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4604 // Items 2-4 are only filled if the property has either a getter or a setter 4619 // Items 2-4 are only filled if the property has either a getter or a setter
4605 // defined through __defineGetter__ and/or __defineSetter__. 4620 // defined through __defineGetter__ and/or __defineSetter__.
4606 static Object* Runtime_DebugGetPropertyDetails(Arguments args) { 4621 static Object* Runtime_DebugGetPropertyDetails(Arguments args) {
4607 HandleScope scope; 4622 HandleScope scope;
4608 4623
4609 ASSERT(args.length() == 2); 4624 ASSERT(args.length() == 2);
4610 4625
4611 CONVERT_ARG_CHECKED(JSObject, obj, 0); 4626 CONVERT_ARG_CHECKED(JSObject, obj, 0);
4612 CONVERT_ARG_CHECKED(String, name, 1); 4627 CONVERT_ARG_CHECKED(String, name, 1);
4613 4628
4629 // Skip the global proxy as it has no properties and always delegates to the
4630 // real global object.
4631 if (obj->IsJSGlobalProxy()) {
4632 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
4633 }
4634
4635
4614 // Check if the name is trivially convertible to an index and get the element 4636 // Check if the name is trivially convertible to an index and get the element
4615 // if so. 4637 // if so.
4616 uint32_t index; 4638 uint32_t index;
4617 if (name->AsArrayIndex(&index)) { 4639 if (name->AsArrayIndex(&index)) {
4618 Handle<FixedArray> details = Factory::NewFixedArray(2); 4640 Handle<FixedArray> details = Factory::NewFixedArray(2);
4619 details->set(0, Runtime::GetElementOrCharAt(obj, index)); 4641 details->set(0, Runtime::GetElementOrCharAt(obj, index));
4620 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); 4642 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi());
4621 return *Factory::NewJSArrayWithElements(details); 4643 return *Factory::NewJSArrayWithElements(details);
4622 } 4644 }
4623 4645
4624 // Perform standard local lookup on the object. 4646 // Find the number of objects making up this.
4647 int length = LocalPrototypeChainLength(*obj);
4648
4649 // Try local lookup on each of the objects.
4625 LookupResult result; 4650 LookupResult result;
4626 obj->LocalLookup(*name, &result); 4651 Handle<JSObject> jsproto = obj;
4652 for (int i = 0; i < length; i++) {
4653 jsproto->LocalLookup(*name, &result);
4654 if (result.IsProperty()) {
4655 break;
4656 }
4657 if (i < length - 1) {
4658 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
4659 }
4660 }
4661
4627 if (result.IsProperty()) { 4662 if (result.IsProperty()) {
4628 bool caught_exception = false; 4663 bool caught_exception = false;
4629 Handle<Object> value(DebugLookupResultValue(*obj, &result, 4664 Handle<Object> value(DebugLookupResultValue(*obj, &result,
4630 &caught_exception)); 4665 &caught_exception));
4631 // If the callback object is a fixed array then it contains JavaScript 4666 // If the callback object is a fixed array then it contains JavaScript
4632 // getter and/or setter. 4667 // getter and/or setter.
4633 bool hasJavaScriptAccessors = result.type() == CALLBACKS && 4668 bool hasJavaScriptAccessors = result.type() == CALLBACKS &&
4634 result.GetCallbackObject()->IsFixedArray(); 4669 result.GetCallbackObject()->IsFixedArray();
4635 Handle<FixedArray> details = 4670 Handle<FixedArray> details =
4636 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); 4671 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4669 // Return the names of the local named properties. 4704 // Return the names of the local named properties.
4670 // args[0]: object 4705 // args[0]: object
4671 static Object* Runtime_DebugLocalPropertyNames(Arguments args) { 4706 static Object* Runtime_DebugLocalPropertyNames(Arguments args) {
4672 HandleScope scope; 4707 HandleScope scope;
4673 ASSERT(args.length() == 1); 4708 ASSERT(args.length() == 1);
4674 if (!args[0]->IsJSObject()) { 4709 if (!args[0]->IsJSObject()) {
4675 return Heap::undefined_value(); 4710 return Heap::undefined_value();
4676 } 4711 }
4677 CONVERT_ARG_CHECKED(JSObject, obj, 0); 4712 CONVERT_ARG_CHECKED(JSObject, obj, 0);
4678 4713
4714 // Skip the global proxy as it has no properties and always delegates to the
4715 // real global object.
4679 if (obj->IsJSGlobalProxy()) { 4716 if (obj->IsJSGlobalProxy()) {
4680 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); 4717 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
4681 } 4718 }
4682 int n = obj->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE)); 4719
4683 Handle<FixedArray> names = Factory::NewFixedArray(n); 4720 // Find the number of objects making up this.
4684 obj->GetLocalPropertyNames(*names); 4721 int length = LocalPrototypeChainLength(*obj);
4722
4723 // Find the number of local properties for each of the objects.
4724 int* local_property_count = NewArray<int>(length);
4725 int total_property_count = 0;
4726 Handle<JSObject> jsproto = obj;
4727 for (int i = 0; i < length; i++) {
4728 int n;
4729 n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
4730 local_property_count[i] = n;
4731 total_property_count += n;
4732 if (i < length - 1) {
4733 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
4734 }
4735 }
4736
4737 // Allocate an array with storage for all the property names.
4738 Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
4739
4740 // Get the property names.
4741 jsproto = obj;
4742 for (int i = 0; i < length; i++) {
4743 jsproto->GetLocalPropertyNames(*names,
4744 i == 0 ? 0 : local_property_count[i - 1]);
4745 if (i < length - 1) {
4746 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
4747 }
4748 }
4749
4750 DeleteArray(local_property_count);
4685 return *Factory::NewJSArrayWithElements(names); 4751 return *Factory::NewJSArrayWithElements(names);
4686 } 4752 }
4687 4753
4688 4754
4689 // Return the names of the local indexed properties. 4755 // Return the names of the local indexed properties.
4690 // args[0]: object 4756 // args[0]: object
4691 static Object* Runtime_DebugLocalElementNames(Arguments args) { 4757 static Object* Runtime_DebugLocalElementNames(Arguments args) {
4692 HandleScope scope; 4758 HandleScope scope;
4693 ASSERT(args.length() == 1); 4759 ASSERT(args.length() == 1);
4694 if (!args[0]->IsJSObject()) { 4760 if (!args[0]->IsJSObject()) {
(...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after
5802 5868
5803 // Return result as JS array. 5869 // Return result as JS array.
5804 Object* result = 5870 Object* result =
5805 Heap::AllocateJSObject( 5871 Heap::AllocateJSObject(
5806 Top::context()->global_context()->array_function()); 5872 Top::context()->global_context()->array_function());
5807 if (!result->IsFailure()) JSArray::cast(result)->SetContent(instances); 5873 if (!result->IsFailure()) JSArray::cast(result)->SetContent(instances);
5808 return result; 5874 return result;
5809 } 5875 }
5810 5876
5811 5877
5812 static Object* Runtime_GetPrototype(Arguments args) { 5878 // Find the effective prototype object as returned by __proto__.
5879 // args[0]: the object to find the prototype for.
5880 static Object* Runtime_DebugGetPrototype(Arguments args) {
5813 ASSERT(args.length() == 1); 5881 ASSERT(args.length() == 1);
5814 5882
5815 CONVERT_CHECKED(JSObject, obj, args[0]); 5883 CONVERT_CHECKED(JSObject, obj, args[0]);
5816 5884
5817 return obj->GetPrototype(); 5885 // Use the __proto__ accessor.
5886 return Accessors::ObjectPrototype.getter(obj, NULL);
5818 } 5887 }
5819 5888
5820 5889
5821 static Object* Runtime_SystemBreak(Arguments args) { 5890 static Object* Runtime_SystemBreak(Arguments args) {
5822 ASSERT(args.length() == 0); 5891 ASSERT(args.length() == 0);
5823 CPU::DebugBreak(); 5892 CPU::DebugBreak();
5824 return Heap::undefined_value(); 5893 return Heap::undefined_value();
5825 } 5894 }
5826 5895
5827 5896
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
5981 } else { 6050 } else {
5982 // Handle last resort GC and make sure to allow future allocations 6051 // Handle last resort GC and make sure to allow future allocations
5983 // to grow the heap without causing GCs (if possible). 6052 // to grow the heap without causing GCs (if possible).
5984 Counters::gc_last_resort_from_js.Increment(); 6053 Counters::gc_last_resort_from_js.Increment();
5985 Heap::CollectAllGarbage(); 6054 Heap::CollectAllGarbage();
5986 } 6055 }
5987 } 6056 }
5988 6057
5989 6058
5990 } } // namespace v8::internal 6059 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | test/cctest/test-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698