| OLD | NEW |
| 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 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 // objects more than once in case of interceptors, because the | 326 // objects more than once in case of interceptors, because the |
| 327 // holder will always be the interceptor holder and the search may | 327 // holder will always be the interceptor holder and the search may |
| 328 // only continue with a current object just after the interceptor | 328 // only continue with a current object just after the interceptor |
| 329 // holder in the prototype chain. | 329 // holder in the prototype chain. |
| 330 Object* last = result->IsValid() ? result->holder() : Heap::null_value(); | 330 Object* last = result->IsValid() ? result->holder() : Heap::null_value(); |
| 331 for (Object* current = this; true; current = current->GetPrototype()) { | 331 for (Object* current = this; true; current = current->GetPrototype()) { |
| 332 if (current->IsAccessCheckNeeded()) { | 332 if (current->IsAccessCheckNeeded()) { |
| 333 // Check if we're allowed to read from the current object. Note | 333 // Check if we're allowed to read from the current object. Note |
| 334 // that even though we may not actually end up loading the named | 334 // that even though we may not actually end up loading the named |
| 335 // property from the current object, we still check that we have | 335 // property from the current object, we still check that we have |
| 336 // access to it. | 336 // access to the it. |
| 337 JSObject* checked = JSObject::cast(current); | 337 JSObject* checked = JSObject::cast(current); |
| 338 if (!Top::MayNamedAccess(checked, name, v8::ACCESS_GET)) { | 338 if (!Top::MayNamedAccess(checked, name, v8::ACCESS_GET)) { |
| 339 return checked->GetPropertyWithFailedAccessCheck(receiver, | 339 return checked->GetPropertyWithFailedAccessCheck(receiver, |
| 340 result, | 340 result, |
| 341 name); | 341 name); |
| 342 } | 342 } |
| 343 } | 343 } |
| 344 // Stop traversing the chain once we reach the last object in the | 344 // Stop traversing the chain once we reach the last object in the |
| 345 // chain; either the holder of the result or null in case of an | 345 // chain; either the holder of the result or null in case of an |
| 346 // absent property. | 346 // absent property. |
| (...skipping 3696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4043 | 4043 |
| 4044 | 4044 |
| 4045 void String::PrintOn(FILE* file) { | 4045 void String::PrintOn(FILE* file) { |
| 4046 int length = this->length(); | 4046 int length = this->length(); |
| 4047 for (int i = 0; i < length; i++) { | 4047 for (int i = 0; i < length; i++) { |
| 4048 fprintf(file, "%c", Get(i)); | 4048 fprintf(file, "%c", Get(i)); |
| 4049 } | 4049 } |
| 4050 } | 4050 } |
| 4051 | 4051 |
| 4052 | 4052 |
| 4053 void Map::CreateBackPointers() { | |
| 4054 DescriptorArray* descriptors = instance_descriptors(); | |
| 4055 for (DescriptorReader r(descriptors); !r.eos(); r.advance()) { | |
| 4056 if (r.type() == MAP_TRANSITION) { | |
| 4057 // Get target. | |
| 4058 Map* target = Map::cast(r.GetValue()); | |
| 4059 #ifdef DEBUG | |
| 4060 // Verify target. | |
| 4061 Object* source_prototype = prototype(); | |
| 4062 Object* target_prototype = target->prototype(); | |
| 4063 ASSERT(source_prototype->IsJSObject() || | |
| 4064 source_prototype->IsMap() || | |
| 4065 source_prototype->IsNull()); | |
| 4066 ASSERT(target_prototype->IsJSObject() || | |
| 4067 target_prototype->IsNull()); | |
| 4068 ASSERT(source_prototype->IsMap() || | |
| 4069 source_prototype == target_prototype); | |
| 4070 #endif | |
| 4071 // Point target back to source. set_prototype() will not let us set | |
| 4072 // the prototype to a map, as we do here. | |
| 4073 RawField(target, kPrototypeOffset) = this; | |
| 4074 } | |
| 4075 } | |
| 4076 } | |
| 4077 | |
| 4078 | |
| 4079 void Map::ClearNonLiveTransitions(Object* real_prototype) { | |
| 4080 // Live DescriptorArray objects will be marked, so we must use | |
| 4081 // low-level accessors to get and modify their data. | |
| 4082 DescriptorArray* d = reinterpret_cast<DescriptorArray*>( | |
| 4083 RawField(this, Map::kInstanceDescriptorsOffset)); | |
| 4084 if (d == Heap::empty_descriptor_array()) return; | |
| 4085 Smi* NullDescriptorDetails = | |
| 4086 PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi(); | |
| 4087 FixedArray* contents = reinterpret_cast<FixedArray*>( | |
| 4088 d->get(DescriptorArray::kContentArrayIndex)); | |
| 4089 ASSERT(contents->length() >= 2); | |
| 4090 for (int i = 0; i < contents->length(); i += 2) { | |
| 4091 // If the pair (value, details) is a map transition, | |
| 4092 // check if the target is live. If not, null the descriptor. | |
| 4093 // Also drop the back pointer for that map transition, so that this | |
| 4094 // map is not reached again by following a back pointer from a | |
| 4095 // non-live object. | |
| 4096 PropertyDetails details(Smi::cast(contents->get(i + 1))); | |
| 4097 if (details.type() == MAP_TRANSITION) { | |
| 4098 Map* target = reinterpret_cast<Map*>(contents->get(i)); | |
| 4099 ASSERT(target->IsHeapObject()); | |
| 4100 if (!target->IsMarked()) { | |
| 4101 ASSERT(target->IsMap()); | |
| 4102 contents->set(i + 1, NullDescriptorDetails, SKIP_WRITE_BARRIER); | |
| 4103 contents->set(i, Heap::null_value(), SKIP_WRITE_BARRIER); | |
| 4104 ASSERT(target->prototype() == this || | |
| 4105 target->prototype() == real_prototype); | |
| 4106 // Getter prototype() is read-only, set_prototype() has side effects. | |
| 4107 RawField(target, Map::kPrototypeOffset) = real_prototype; | |
| 4108 } | |
| 4109 } | |
| 4110 } | |
| 4111 } | |
| 4112 | |
| 4113 | |
| 4114 void Map::MapIterateBody(ObjectVisitor* v) { | 4053 void Map::MapIterateBody(ObjectVisitor* v) { |
| 4115 // Assumes all Object* members are contiguously allocated! | 4054 // Assumes all Object* members are contiguously allocated! |
| 4116 IteratePointers(v, kPrototypeOffset, kCodeCacheOffset + kPointerSize); | 4055 IteratePointers(v, kPrototypeOffset, kCodeCacheOffset + kPointerSize); |
| 4117 } | 4056 } |
| 4118 | 4057 |
| 4119 | 4058 |
| 4120 Object* JSFunction::SetInstancePrototype(Object* value) { | 4059 Object* JSFunction::SetInstancePrototype(Object* value) { |
| 4121 ASSERT(value->IsJSObject()); | 4060 ASSERT(value->IsJSObject()); |
| 4122 | 4061 |
| 4123 if (has_initial_map()) { | 4062 if (has_initial_map()) { |
| (...skipping 2659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6783 // No break point. | 6722 // No break point. |
| 6784 if (break_point_objects()->IsUndefined()) return 0; | 6723 if (break_point_objects()->IsUndefined()) return 0; |
| 6785 // Single beak point. | 6724 // Single beak point. |
| 6786 if (!break_point_objects()->IsFixedArray()) return 1; | 6725 if (!break_point_objects()->IsFixedArray()) return 1; |
| 6787 // Multiple break points. | 6726 // Multiple break points. |
| 6788 return FixedArray::cast(break_point_objects())->length(); | 6727 return FixedArray::cast(break_point_objects())->length(); |
| 6789 } | 6728 } |
| 6790 | 6729 |
| 6791 | 6730 |
| 6792 } } // namespace v8::internal | 6731 } } // namespace v8::internal |
| OLD | NEW |