OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 15 matching lines...) Expand all Loading... |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "api.h" | 30 #include "api.h" |
31 #include "arguments.h" | 31 #include "arguments.h" |
32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
33 #include "debug.h" | 33 #include "debug.h" |
34 #include "execution.h" | 34 #include "execution.h" |
35 #include "objects-inl.h" | 35 #include "objects-inl.h" |
| 36 #include "objects-visiting.h" |
36 #include "macro-assembler.h" | 37 #include "macro-assembler.h" |
37 #include "scanner.h" | 38 #include "scanner.h" |
38 #include "scopeinfo.h" | 39 #include "scopeinfo.h" |
39 #include "string-stream.h" | 40 #include "string-stream.h" |
40 #include "utils.h" | 41 #include "utils.h" |
41 | 42 |
42 #ifdef ENABLE_DISASSEMBLER | 43 #ifdef ENABLE_DISASSEMBLER |
43 #include "disassembler.h" | 44 #include "disassembler.h" |
44 #endif | 45 #endif |
45 | 46 |
(...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 SeqAsciiString* seq_ascii_this = reinterpret_cast<SeqAsciiString*>(this); | 1036 SeqAsciiString* seq_ascii_this = reinterpret_cast<SeqAsciiString*>(this); |
1036 return seq_ascii_this->SeqAsciiStringSize(instance_type); | 1037 return seq_ascii_this->SeqAsciiStringSize(instance_type); |
1037 } else { | 1038 } else { |
1038 SeqTwoByteString* self = reinterpret_cast<SeqTwoByteString*>(this); | 1039 SeqTwoByteString* self = reinterpret_cast<SeqTwoByteString*>(this); |
1039 return self->SeqTwoByteStringSize(instance_type); | 1040 return self->SeqTwoByteStringSize(instance_type); |
1040 } | 1041 } |
1041 } | 1042 } |
1042 | 1043 |
1043 switch (instance_type) { | 1044 switch (instance_type) { |
1044 case FIXED_ARRAY_TYPE: | 1045 case FIXED_ARRAY_TYPE: |
1045 return reinterpret_cast<FixedArray*>(this)->FixedArraySize(); | 1046 return FixedArray::BodyDescriptor::SizeOf(map, this); |
1046 case BYTE_ARRAY_TYPE: | 1047 case BYTE_ARRAY_TYPE: |
1047 return reinterpret_cast<ByteArray*>(this)->ByteArraySize(); | 1048 return reinterpret_cast<ByteArray*>(this)->ByteArraySize(); |
1048 case CODE_TYPE: | 1049 case CODE_TYPE: |
1049 return reinterpret_cast<Code*>(this)->CodeSize(); | 1050 return reinterpret_cast<Code*>(this)->CodeSize(); |
1050 case MAP_TYPE: | 1051 case MAP_TYPE: |
1051 return Map::kSize; | 1052 return Map::kSize; |
1052 default: | 1053 default: |
1053 return map->instance_size(); | 1054 return map->instance_size(); |
1054 } | 1055 } |
1055 } | 1056 } |
(...skipping 10 matching lines...) Expand all Loading... |
1066 | 1067 |
1067 void HeapObject::IterateBody(InstanceType type, int object_size, | 1068 void HeapObject::IterateBody(InstanceType type, int object_size, |
1068 ObjectVisitor* v) { | 1069 ObjectVisitor* v) { |
1069 // Avoiding <Type>::cast(this) because it accesses the map pointer field. | 1070 // Avoiding <Type>::cast(this) because it accesses the map pointer field. |
1070 // During GC, the map pointer field is encoded. | 1071 // During GC, the map pointer field is encoded. |
1071 if (type < FIRST_NONSTRING_TYPE) { | 1072 if (type < FIRST_NONSTRING_TYPE) { |
1072 switch (type & kStringRepresentationMask) { | 1073 switch (type & kStringRepresentationMask) { |
1073 case kSeqStringTag: | 1074 case kSeqStringTag: |
1074 break; | 1075 break; |
1075 case kConsStringTag: | 1076 case kConsStringTag: |
1076 reinterpret_cast<ConsString*>(this)->ConsStringIterateBody(v); | 1077 ConsString::BodyDescriptor::IterateBody(this, v); |
1077 break; | 1078 break; |
1078 case kExternalStringTag: | 1079 case kExternalStringTag: |
1079 if ((type & kStringEncodingMask) == kAsciiStringTag) { | 1080 if ((type & kStringEncodingMask) == kAsciiStringTag) { |
1080 reinterpret_cast<ExternalAsciiString*>(this)-> | 1081 reinterpret_cast<ExternalAsciiString*>(this)-> |
1081 ExternalAsciiStringIterateBody(v); | 1082 ExternalAsciiStringIterateBody(v); |
1082 } else { | 1083 } else { |
1083 reinterpret_cast<ExternalTwoByteString*>(this)-> | 1084 reinterpret_cast<ExternalTwoByteString*>(this)-> |
1084 ExternalTwoByteStringIterateBody(v); | 1085 ExternalTwoByteStringIterateBody(v); |
1085 } | 1086 } |
1086 break; | 1087 break; |
1087 } | 1088 } |
1088 return; | 1089 return; |
1089 } | 1090 } |
1090 | 1091 |
1091 switch (type) { | 1092 switch (type) { |
1092 case FIXED_ARRAY_TYPE: | 1093 case FIXED_ARRAY_TYPE: |
1093 reinterpret_cast<FixedArray*>(this)->FixedArrayIterateBody(v); | 1094 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); |
1094 break; | 1095 break; |
1095 case JS_OBJECT_TYPE: | 1096 case JS_OBJECT_TYPE: |
1096 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: | 1097 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: |
1097 case JS_VALUE_TYPE: | 1098 case JS_VALUE_TYPE: |
1098 case JS_ARRAY_TYPE: | 1099 case JS_ARRAY_TYPE: |
1099 case JS_REGEXP_TYPE: | 1100 case JS_REGEXP_TYPE: |
1100 case JS_FUNCTION_TYPE: | 1101 case JS_FUNCTION_TYPE: |
1101 case JS_GLOBAL_PROXY_TYPE: | 1102 case JS_GLOBAL_PROXY_TYPE: |
1102 case JS_GLOBAL_OBJECT_TYPE: | 1103 case JS_GLOBAL_OBJECT_TYPE: |
1103 case JS_BUILTINS_OBJECT_TYPE: | 1104 case JS_BUILTINS_OBJECT_TYPE: |
1104 reinterpret_cast<JSObject*>(this)->JSObjectIterateBody(object_size, v); | 1105 JSObject::BodyDescriptor::IterateBody(this, object_size, v); |
1105 break; | 1106 break; |
1106 case ODDBALL_TYPE: | 1107 case ODDBALL_TYPE: |
1107 reinterpret_cast<Oddball*>(this)->OddballIterateBody(v); | 1108 Oddball::BodyDescriptor::IterateBody(this, v); |
1108 break; | 1109 break; |
1109 case PROXY_TYPE: | 1110 case PROXY_TYPE: |
1110 reinterpret_cast<Proxy*>(this)->ProxyIterateBody(v); | 1111 reinterpret_cast<Proxy*>(this)->ProxyIterateBody(v); |
1111 break; | 1112 break; |
1112 case MAP_TYPE: | 1113 case MAP_TYPE: |
1113 reinterpret_cast<Map*>(this)->MapIterateBody(v); | 1114 Map::BodyDescriptor::IterateBody(this, v); |
1114 break; | 1115 break; |
1115 case CODE_TYPE: | 1116 case CODE_TYPE: |
1116 reinterpret_cast<Code*>(this)->CodeIterateBody(v); | 1117 reinterpret_cast<Code*>(this)->CodeIterateBody(v); |
1117 break; | 1118 break; |
1118 case JS_GLOBAL_PROPERTY_CELL_TYPE: | 1119 case JS_GLOBAL_PROPERTY_CELL_TYPE: |
1119 reinterpret_cast<JSGlobalPropertyCell*>(this) | 1120 JSGlobalPropertyCell::BodyDescriptor::IterateBody(this, v); |
1120 ->JSGlobalPropertyCellIterateBody(v); | |
1121 break; | 1121 break; |
1122 case HEAP_NUMBER_TYPE: | 1122 case HEAP_NUMBER_TYPE: |
1123 case FILLER_TYPE: | 1123 case FILLER_TYPE: |
1124 case BYTE_ARRAY_TYPE: | 1124 case BYTE_ARRAY_TYPE: |
1125 case PIXEL_ARRAY_TYPE: | 1125 case PIXEL_ARRAY_TYPE: |
1126 case EXTERNAL_BYTE_ARRAY_TYPE: | 1126 case EXTERNAL_BYTE_ARRAY_TYPE: |
1127 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: | 1127 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: |
1128 case EXTERNAL_SHORT_ARRAY_TYPE: | 1128 case EXTERNAL_SHORT_ARRAY_TYPE: |
1129 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: | 1129 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: |
1130 case EXTERNAL_INT_ARRAY_TYPE: | 1130 case EXTERNAL_INT_ARRAY_TYPE: |
1131 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: | 1131 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: |
1132 case EXTERNAL_FLOAT_ARRAY_TYPE: | 1132 case EXTERNAL_FLOAT_ARRAY_TYPE: |
1133 break; | 1133 break; |
1134 case SHARED_FUNCTION_INFO_TYPE: { | 1134 case SHARED_FUNCTION_INFO_TYPE: |
1135 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(this); | 1135 SharedFunctionInfo::BodyDescriptor::IterateBody(this, v); |
1136 shared->SharedFunctionInfoIterateBody(v); | |
1137 break; | 1136 break; |
1138 } | 1137 |
1139 #define MAKE_STRUCT_CASE(NAME, Name, name) \ | 1138 #define MAKE_STRUCT_CASE(NAME, Name, name) \ |
1140 case NAME##_TYPE: | 1139 case NAME##_TYPE: |
1141 STRUCT_LIST(MAKE_STRUCT_CASE) | 1140 STRUCT_LIST(MAKE_STRUCT_CASE) |
1142 #undef MAKE_STRUCT_CASE | 1141 #undef MAKE_STRUCT_CASE |
1143 IterateStructBody(object_size, v); | 1142 StructBodyDescriptor::IterateBody(this, object_size, v); |
1144 break; | 1143 break; |
1145 default: | 1144 default: |
1146 PrintF("Unknown type: %d\n", type); | 1145 PrintF("Unknown type: %d\n", type); |
1147 UNREACHABLE(); | 1146 UNREACHABLE(); |
1148 } | 1147 } |
1149 } | 1148 } |
1150 | 1149 |
1151 | 1150 |
1152 void HeapObject::IterateStructBody(int object_size, ObjectVisitor* v) { | 1151 void HeapObject::IterateStructBody(int object_size, ObjectVisitor* v) { |
1153 IteratePointers(v, HeapObject::kHeaderSize, object_size); | 1152 IteratePointers(v, HeapObject::kHeaderSize, object_size); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 if (map()->constructor()->IsJSFunction()) { | 1201 if (map()->constructor()->IsJSFunction()) { |
1203 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1202 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
1204 String* name = String::cast(constructor->shared()->name()); | 1203 String* name = String::cast(constructor->shared()->name()); |
1205 return name->length() > 0 ? name : constructor->shared()->inferred_name(); | 1204 return name->length() > 0 ? name : constructor->shared()->inferred_name(); |
1206 } | 1205 } |
1207 // If the constructor is not present, return "Object". | 1206 // If the constructor is not present, return "Object". |
1208 return Heap::Object_symbol(); | 1207 return Heap::Object_symbol(); |
1209 } | 1208 } |
1210 | 1209 |
1211 | 1210 |
1212 void JSObject::JSObjectIterateBody(int object_size, ObjectVisitor* v) { | |
1213 // Iterate over all fields in the body. Assumes all are Object*. | |
1214 IteratePointers(v, kPropertiesOffset, object_size); | |
1215 } | |
1216 | |
1217 | |
1218 Object* JSObject::AddFastPropertyUsingMap(Map* new_map, | 1211 Object* JSObject::AddFastPropertyUsingMap(Map* new_map, |
1219 String* name, | 1212 String* name, |
1220 Object* value) { | 1213 Object* value) { |
1221 int index = new_map->PropertyIndexFor(name); | 1214 int index = new_map->PropertyIndexFor(name); |
1222 if (map()->unused_property_fields() == 0) { | 1215 if (map()->unused_property_fields() == 0) { |
1223 ASSERT(map()->unused_property_fields() == 0); | 1216 ASSERT(map()->unused_property_fields() == 0); |
1224 int new_unused = new_map->unused_property_fields(); | 1217 int new_unused = new_map->unused_property_fields(); |
1225 Object* values = | 1218 Object* values = |
1226 properties()->CopySize(properties()->length() + new_unused + 1); | 1219 properties()->CopySize(properties()->length() + new_unused + 1); |
1227 if (values->IsFailure()) return values; | 1220 if (values->IsFailure()) return values; |
(...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2183 if (obj->IsFailure()) return obj; | 2176 if (obj->IsFailure()) return obj; |
2184 Map* new_map = Map::cast(obj); | 2177 Map* new_map = Map::cast(obj); |
2185 | 2178 |
2186 // Clear inobject properties if needed by adjusting the instance size and | 2179 // Clear inobject properties if needed by adjusting the instance size and |
2187 // putting in a filler object instead of the inobject properties. | 2180 // putting in a filler object instead of the inobject properties. |
2188 if (mode == CLEAR_INOBJECT_PROPERTIES && map()->inobject_properties() > 0) { | 2181 if (mode == CLEAR_INOBJECT_PROPERTIES && map()->inobject_properties() > 0) { |
2189 int instance_size_delta = map()->inobject_properties() * kPointerSize; | 2182 int instance_size_delta = map()->inobject_properties() * kPointerSize; |
2190 int new_instance_size = map()->instance_size() - instance_size_delta; | 2183 int new_instance_size = map()->instance_size() - instance_size_delta; |
2191 new_map->set_inobject_properties(0); | 2184 new_map->set_inobject_properties(0); |
2192 new_map->set_instance_size(new_instance_size); | 2185 new_map->set_instance_size(new_instance_size); |
2193 new_map->set_scavenger(Heap::GetScavenger(new_map->instance_type(), | 2186 new_map->set_visitor_id(StaticVisitorBase::GetVisitorId(new_map)); |
2194 new_map->instance_size())); | |
2195 Heap::CreateFillerObjectAt(this->address() + new_instance_size, | 2187 Heap::CreateFillerObjectAt(this->address() + new_instance_size, |
2196 instance_size_delta); | 2188 instance_size_delta); |
2197 } | 2189 } |
2198 new_map->set_unused_property_fields(0); | 2190 new_map->set_unused_property_fields(0); |
2199 | 2191 |
2200 // We have now successfully allocated all the necessary objects. | 2192 // We have now successfully allocated all the necessary objects. |
2201 // Changes can now be made with the guarantee that all of them take effect. | 2193 // Changes can now be made with the guarantee that all of them take effect. |
2202 set_map(new_map); | 2194 set_map(new_map); |
2203 map()->set_instance_descriptors(Heap::empty_descriptor_array()); | 2195 map()->set_instance_descriptors(Heap::empty_descriptor_array()); |
2204 | 2196 |
(...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3400 | 3392 |
3401 | 3393 |
3402 void CodeCacheHashTable::RemoveByIndex(int index) { | 3394 void CodeCacheHashTable::RemoveByIndex(int index) { |
3403 ASSERT(index >= 0); | 3395 ASSERT(index >= 0); |
3404 set(EntryToIndex(index), Heap::null_value()); | 3396 set(EntryToIndex(index), Heap::null_value()); |
3405 set(EntryToIndex(index) + 1, Heap::null_value()); | 3397 set(EntryToIndex(index) + 1, Heap::null_value()); |
3406 ElementRemoved(); | 3398 ElementRemoved(); |
3407 } | 3399 } |
3408 | 3400 |
3409 | 3401 |
3410 void FixedArray::FixedArrayIterateBody(ObjectVisitor* v) { | |
3411 IteratePointers(v, kHeaderSize, kHeaderSize + length() * kPointerSize); | |
3412 } | |
3413 | |
3414 | |
3415 static bool HasKey(FixedArray* array, Object* key) { | 3402 static bool HasKey(FixedArray* array, Object* key) { |
3416 int len0 = array->length(); | 3403 int len0 = array->length(); |
3417 for (int i = 0; i < len0; i++) { | 3404 for (int i = 0; i < len0; i++) { |
3418 Object* element = array->get(i); | 3405 Object* element = array->get(i); |
3419 if (element->IsSmi() && key->IsSmi() && (element == key)) return true; | 3406 if (element->IsSmi() && key->IsSmi() && (element == key)) return true; |
3420 if (element->IsString() && | 3407 if (element->IsString() && |
3421 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | 3408 key->IsString() && String::cast(element)->Equals(String::cast(key))) { |
3422 return true; | 3409 return true; |
3423 } | 3410 } |
3424 } | 3411 } |
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4494 offset_correction += left_length; | 4481 offset_correction += left_length; |
4495 String::ReadBlockIntoBuffer(right, rbb, &offset, max_chars); | 4482 String::ReadBlockIntoBuffer(right, rbb, &offset, max_chars); |
4496 } | 4483 } |
4497 *offset_ptr = offset + offset_correction; | 4484 *offset_ptr = offset + offset_correction; |
4498 return; | 4485 return; |
4499 } | 4486 } |
4500 } | 4487 } |
4501 } | 4488 } |
4502 | 4489 |
4503 | 4490 |
4504 void ConsString::ConsStringIterateBody(ObjectVisitor* v) { | |
4505 IteratePointers(v, kFirstOffset, kSecondOffset + kPointerSize); | |
4506 } | |
4507 | |
4508 | |
4509 void JSGlobalPropertyCell::JSGlobalPropertyCellIterateBody(ObjectVisitor* v) { | |
4510 IteratePointers(v, kValueOffset, kValueOffset + kPointerSize); | |
4511 } | |
4512 | |
4513 | |
4514 uint16_t ConsString::ConsStringGet(int index) { | 4491 uint16_t ConsString::ConsStringGet(int index) { |
4515 ASSERT(index >= 0 && index < this->length()); | 4492 ASSERT(index >= 0 && index < this->length()); |
4516 | 4493 |
4517 // Check for a flattened cons string | 4494 // Check for a flattened cons string |
4518 if (second()->length() == 0) { | 4495 if (second()->length() == 0) { |
4519 String* left = first(); | 4496 String* left = first(); |
4520 return left->Get(index); | 4497 return left->Get(index); |
4521 } | 4498 } |
4522 | 4499 |
4523 String* string = String::cast(this); | 4500 String* string = String::cast(this); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4607 } | 4584 } |
4608 source = first; | 4585 source = first; |
4609 } | 4586 } |
4610 break; | 4587 break; |
4611 } | 4588 } |
4612 } | 4589 } |
4613 } | 4590 } |
4614 } | 4591 } |
4615 | 4592 |
4616 | 4593 |
4617 #define FIELD_ADDR(p, offset) \ | |
4618 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) | |
4619 | |
4620 void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) { | |
4621 typedef v8::String::ExternalAsciiStringResource Resource; | |
4622 v->VisitExternalAsciiString( | |
4623 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset))); | |
4624 } | |
4625 | |
4626 | |
4627 void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) { | |
4628 typedef v8::String::ExternalStringResource Resource; | |
4629 v->VisitExternalTwoByteString( | |
4630 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset))); | |
4631 } | |
4632 | |
4633 #undef FIELD_ADDR | |
4634 | |
4635 template <typename IteratorA, typename IteratorB> | 4594 template <typename IteratorA, typename IteratorB> |
4636 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { | 4595 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { |
4637 // General slow case check. We know that the ia and ib iterators | 4596 // General slow case check. We know that the ia and ib iterators |
4638 // have the same length. | 4597 // have the same length. |
4639 while (ia->has_more()) { | 4598 while (ia->has_more()) { |
4640 uc32 ca = ia->GetNext(); | 4599 uc32 ca = ia->GetNext(); |
4641 uc32 cb = ib->GetNext(); | 4600 uc32 cb = ib->GetNext(); |
4642 if (ca != cb) | 4601 if (ca != cb) |
4643 return false; | 4602 return false; |
4644 } | 4603 } |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5028 ASSERT(target->prototype() == this || | 4987 ASSERT(target->prototype() == this || |
5029 target->prototype() == real_prototype); | 4988 target->prototype() == real_prototype); |
5030 // Getter prototype() is read-only, set_prototype() has side effects. | 4989 // Getter prototype() is read-only, set_prototype() has side effects. |
5031 *RawField(target, Map::kPrototypeOffset) = real_prototype; | 4990 *RawField(target, Map::kPrototypeOffset) = real_prototype; |
5032 } | 4991 } |
5033 } | 4992 } |
5034 } | 4993 } |
5035 } | 4994 } |
5036 | 4995 |
5037 | 4996 |
5038 void Map::MapIterateBody(ObjectVisitor* v) { | |
5039 // Assumes all Object* members are contiguously allocated! | |
5040 IteratePointers(v, kPointerFieldsBeginOffset, kPointerFieldsEndOffset); | |
5041 } | |
5042 | |
5043 | |
5044 Object* JSFunction::SetInstancePrototype(Object* value) { | 4997 Object* JSFunction::SetInstancePrototype(Object* value) { |
5045 ASSERT(value->IsJSObject()); | 4998 ASSERT(value->IsJSObject()); |
5046 | 4999 |
5047 if (has_initial_map()) { | 5000 if (has_initial_map()) { |
5048 initial_map()->set_prototype(value); | 5001 initial_map()->set_prototype(value); |
5049 } else { | 5002 } else { |
5050 // Put the value in the initial map field until an initial map is | 5003 // Put the value in the initial map field until an initial map is |
5051 // needed. At that point, a new initial map is created and the | 5004 // needed. At that point, a new initial map is created and the |
5052 // prototype is put into the initial map where it belongs. | 5005 // prototype is put into the initial map where it belongs. |
5053 set_prototype_or_initial_map(value); | 5006 set_prototype_or_initial_map(value); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5097 shared()->set_instance_class_name(name); | 5050 shared()->set_instance_class_name(name); |
5098 return this; | 5051 return this; |
5099 } | 5052 } |
5100 | 5053 |
5101 | 5054 |
5102 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { | 5055 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { |
5103 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); | 5056 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); |
5104 } | 5057 } |
5105 | 5058 |
5106 | 5059 |
5107 void Oddball::OddballIterateBody(ObjectVisitor* v) { | |
5108 // Assumes all Object* members are contiguously allocated! | |
5109 IteratePointers(v, kToStringOffset, kToNumberOffset + kPointerSize); | |
5110 } | |
5111 | |
5112 | |
5113 Object* Oddball::Initialize(const char* to_string, Object* to_number) { | 5060 Object* Oddball::Initialize(const char* to_string, Object* to_number) { |
5114 Object* symbol = Heap::LookupAsciiSymbol(to_string); | 5061 Object* symbol = Heap::LookupAsciiSymbol(to_string); |
5115 if (symbol->IsFailure()) return symbol; | 5062 if (symbol->IsFailure()) return symbol; |
5116 set_to_string(String::cast(symbol)); | 5063 set_to_string(String::cast(symbol)); |
5117 set_to_number(to_number); | 5064 set_to_number(to_number); |
5118 return this; | 5065 return this; |
5119 } | 5066 } |
5120 | 5067 |
5121 | 5068 |
5122 bool SharedFunctionInfo::HasSourceCode() { | 5069 bool SharedFunctionInfo::HasSourceCode() { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5275 accumulator->Put(script_source, | 5222 accumulator->Put(script_source, |
5276 start_position(), | 5223 start_position(), |
5277 start_position() + max_length); | 5224 start_position() + max_length); |
5278 accumulator->Add("...\n"); | 5225 accumulator->Add("...\n"); |
5279 } else { | 5226 } else { |
5280 accumulator->Put(script_source, start_position(), end_position()); | 5227 accumulator->Put(script_source, start_position(), end_position()); |
5281 } | 5228 } |
5282 } | 5229 } |
5283 | 5230 |
5284 | 5231 |
5285 void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) { | |
5286 IteratePointers(v, | |
5287 kNameOffset, | |
5288 kThisPropertyAssignmentsOffset + kPointerSize); | |
5289 } | |
5290 | |
5291 | |
5292 void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) { | 5232 void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) { |
5293 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 5233 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
5294 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 5234 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
5295 Object* old_target = target; | 5235 Object* old_target = target; |
5296 VisitPointer(&target); | 5236 VisitPointer(&target); |
5297 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. | 5237 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
5298 } | 5238 } |
5299 | 5239 |
5300 | 5240 |
5301 void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { | 5241 void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { |
5302 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 5242 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && |
5303 rinfo->IsPatchedReturnSequence()) || | 5243 rinfo->IsPatchedReturnSequence()) || |
5304 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 5244 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
5305 rinfo->IsPatchedDebugBreakSlotSequence())); | 5245 rinfo->IsPatchedDebugBreakSlotSequence())); |
5306 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 5246 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
5307 Object* old_target = target; | 5247 Object* old_target = target; |
5308 VisitPointer(&target); | 5248 VisitPointer(&target); |
5309 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. | 5249 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
5310 } | 5250 } |
5311 | 5251 |
5312 | 5252 |
5313 void Code::CodeIterateBody(ObjectVisitor* v) { | |
5314 int mode_mask = RelocInfo::kCodeTargetMask | | |
5315 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | | |
5316 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | | |
5317 RelocInfo::ModeMask(RelocInfo::JS_RETURN) | | |
5318 RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) | | |
5319 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); | |
5320 | |
5321 // Use the relocation info pointer before it is visited by | |
5322 // the heap compaction in the next statement. | |
5323 RelocIterator it(this, mode_mask); | |
5324 | |
5325 IteratePointers(v, | |
5326 kRelocationInfoOffset, | |
5327 kRelocationInfoOffset + kPointerSize); | |
5328 | |
5329 for (; !it.done(); it.next()) { | |
5330 it.rinfo()->Visit(v); | |
5331 } | |
5332 } | |
5333 | |
5334 | |
5335 void Code::Relocate(intptr_t delta) { | 5253 void Code::Relocate(intptr_t delta) { |
5336 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { | 5254 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { |
5337 it.rinfo()->apply(delta); | 5255 it.rinfo()->apply(delta); |
5338 } | 5256 } |
5339 CPU::FlushICache(instruction_start(), instruction_size()); | 5257 CPU::FlushICache(instruction_start(), instruction_size()); |
5340 } | 5258 } |
5341 | 5259 |
5342 | 5260 |
5343 void Code::CopyFrom(const CodeDesc& desc) { | 5261 void Code::CopyFrom(const CodeDesc& desc) { |
5344 // copy code | 5262 // copy code |
(...skipping 3466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8811 if (break_point_objects()->IsUndefined()) return 0; | 8729 if (break_point_objects()->IsUndefined()) return 0; |
8812 // Single beak point. | 8730 // Single beak point. |
8813 if (!break_point_objects()->IsFixedArray()) return 1; | 8731 if (!break_point_objects()->IsFixedArray()) return 1; |
8814 // Multiple break points. | 8732 // Multiple break points. |
8815 return FixedArray::cast(break_point_objects())->length(); | 8733 return FixedArray::cast(break_point_objects())->length(); |
8816 } | 8734 } |
8817 #endif | 8735 #endif |
8818 | 8736 |
8819 | 8737 |
8820 } } // namespace v8::internal | 8738 } } // namespace v8::internal |
OLD | NEW |