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 the it. | 336 // access to 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 3698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4045 | 4045 |
4046 | 4046 |
4047 void String::PrintOn(FILE* file) { | 4047 void String::PrintOn(FILE* file) { |
4048 int length = this->length(); | 4048 int length = this->length(); |
4049 for (int i = 0; i < length; i++) { | 4049 for (int i = 0; i < length; i++) { |
4050 fprintf(file, "%c", Get(i)); | 4050 fprintf(file, "%c", Get(i)); |
4051 } | 4051 } |
4052 } | 4052 } |
4053 | 4053 |
4054 | 4054 |
| 4055 void Map::CreateBackPointers() { |
| 4056 DescriptorArray* descriptors = instance_descriptors(); |
| 4057 for (DescriptorReader r(descriptors); !r.eos(); r.advance()) { |
| 4058 if (r.type() == MAP_TRANSITION) { |
| 4059 // Get target. |
| 4060 Map* target = Map::cast(r.GetValue()); |
| 4061 #ifdef DEBUG |
| 4062 // Verify target. |
| 4063 Object* source_prototype = prototype(); |
| 4064 Object* target_prototype = target->prototype(); |
| 4065 ASSERT(source_prototype->IsJSObject() || |
| 4066 source_prototype->IsMap() || |
| 4067 source_prototype->IsNull()); |
| 4068 ASSERT(target_prototype->IsJSObject() || |
| 4069 target_prototype->IsNull()); |
| 4070 ASSERT(source_prototype->IsMap() || |
| 4071 source_prototype == target_prototype); |
| 4072 #endif |
| 4073 // Point target back to source. set_prototype() will not let us set |
| 4074 // the prototype to a map, as we do here. |
| 4075 *RawField(target, kPrototypeOffset) = this; |
| 4076 } |
| 4077 } |
| 4078 } |
| 4079 |
| 4080 |
| 4081 void Map::ClearNonLiveTransitions(Object* real_prototype) { |
| 4082 // Live DescriptorArray objects will be marked, so we must use |
| 4083 // low-level accessors to get and modify their data. |
| 4084 DescriptorArray* d = reinterpret_cast<DescriptorArray*>( |
| 4085 *RawField(this, Map::kInstanceDescriptorsOffset)); |
| 4086 if (d == Heap::empty_descriptor_array()) return; |
| 4087 Smi* NullDescriptorDetails = |
| 4088 PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi(); |
| 4089 FixedArray* contents = reinterpret_cast<FixedArray*>( |
| 4090 d->get(DescriptorArray::kContentArrayIndex)); |
| 4091 ASSERT(contents->length() >= 2); |
| 4092 for (int i = 0; i < contents->length(); i += 2) { |
| 4093 // If the pair (value, details) is a map transition, |
| 4094 // check if the target is live. If not, null the descriptor. |
| 4095 // Also drop the back pointer for that map transition, so that this |
| 4096 // map is not reached again by following a back pointer from a |
| 4097 // non-live object. |
| 4098 PropertyDetails details(Smi::cast(contents->get(i + 1))); |
| 4099 if (details.type() == MAP_TRANSITION) { |
| 4100 Map* target = reinterpret_cast<Map*>(contents->get(i)); |
| 4101 ASSERT(target->IsHeapObject()); |
| 4102 if (!target->IsMarked()) { |
| 4103 ASSERT(target->IsMap()); |
| 4104 contents->set(i + 1, NullDescriptorDetails, SKIP_WRITE_BARRIER); |
| 4105 contents->set(i, Heap::null_value(), SKIP_WRITE_BARRIER); |
| 4106 ASSERT(target->prototype() == this || |
| 4107 target->prototype() == real_prototype); |
| 4108 // Getter prototype() is read-only, set_prototype() has side effects. |
| 4109 *RawField(target, Map::kPrototypeOffset) = real_prototype; |
| 4110 } |
| 4111 } |
| 4112 } |
| 4113 } |
| 4114 |
| 4115 |
4055 void Map::MapIterateBody(ObjectVisitor* v) { | 4116 void Map::MapIterateBody(ObjectVisitor* v) { |
4056 // Assumes all Object* members are contiguously allocated! | 4117 // Assumes all Object* members are contiguously allocated! |
4057 IteratePointers(v, kPrototypeOffset, kCodeCacheOffset + kPointerSize); | 4118 IteratePointers(v, kPrototypeOffset, kCodeCacheOffset + kPointerSize); |
4058 } | 4119 } |
4059 | 4120 |
4060 | 4121 |
4061 Object* JSFunction::SetInstancePrototype(Object* value) { | 4122 Object* JSFunction::SetInstancePrototype(Object* value) { |
4062 ASSERT(value->IsJSObject()); | 4123 ASSERT(value->IsJSObject()); |
4063 | 4124 |
4064 if (has_initial_map()) { | 4125 if (has_initial_map()) { |
(...skipping 2659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6724 // No break point. | 6785 // No break point. |
6725 if (break_point_objects()->IsUndefined()) return 0; | 6786 if (break_point_objects()->IsUndefined()) return 0; |
6726 // Single beak point. | 6787 // Single beak point. |
6727 if (!break_point_objects()->IsFixedArray()) return 1; | 6788 if (!break_point_objects()->IsFixedArray()) return 1; |
6728 // Multiple break points. | 6789 // Multiple break points. |
6729 return FixedArray::cast(break_point_objects())->length(); | 6790 return FixedArray::cast(break_point_objects())->length(); |
6730 } | 6791 } |
6731 | 6792 |
6732 | 6793 |
6733 } } // namespace v8::internal | 6794 } } // namespace v8::internal |
OLD | NEW |