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 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 accumulator->Add("Cell for "); | 1017 accumulator->Add("Cell for "); |
1018 JSGlobalPropertyCell::cast(this)->value()->ShortPrint(accumulator); | 1018 JSGlobalPropertyCell::cast(this)->value()->ShortPrint(accumulator); |
1019 break; | 1019 break; |
1020 default: | 1020 default: |
1021 accumulator->Add("<Other heap object (%d)>", map()->instance_type()); | 1021 accumulator->Add("<Other heap object (%d)>", map()->instance_type()); |
1022 break; | 1022 break; |
1023 } | 1023 } |
1024 } | 1024 } |
1025 | 1025 |
1026 | 1026 |
1027 int HeapObject::SlowSizeFromMap(Map* map) { | |
1028 // Avoid calling functions such as FixedArray::cast during GC, which | |
1029 // read map pointer of this object again. | |
1030 InstanceType instance_type = map->instance_type(); | |
1031 uint32_t type = static_cast<uint32_t>(instance_type); | |
1032 | |
1033 if (instance_type < FIRST_NONSTRING_TYPE | |
1034 && (StringShape(instance_type).IsSequential())) { | |
1035 if ((type & kStringEncodingMask) == kAsciiStringTag) { | |
1036 SeqAsciiString* seq_ascii_this = reinterpret_cast<SeqAsciiString*>(this); | |
1037 return seq_ascii_this->SeqAsciiStringSize(instance_type); | |
1038 } else { | |
1039 SeqTwoByteString* self = reinterpret_cast<SeqTwoByteString*>(this); | |
1040 return self->SeqTwoByteStringSize(instance_type); | |
1041 } | |
1042 } | |
1043 | |
1044 switch (instance_type) { | |
1045 case FIXED_ARRAY_TYPE: | |
1046 return FixedArray::BodyDescriptor::SizeOf(map, this); | |
1047 case BYTE_ARRAY_TYPE: | |
1048 return reinterpret_cast<ByteArray*>(this)->ByteArraySize(); | |
1049 case CODE_TYPE: | |
1050 return reinterpret_cast<Code*>(this)->CodeSize(); | |
1051 case MAP_TYPE: | |
1052 return Map::kSize; | |
1053 default: | |
1054 return map->instance_size(); | |
1055 } | |
1056 } | |
1057 | |
1058 | |
1059 void HeapObject::Iterate(ObjectVisitor* v) { | 1027 void HeapObject::Iterate(ObjectVisitor* v) { |
1060 // Handle header | 1028 // Handle header |
1061 IteratePointer(v, kMapOffset); | 1029 IteratePointer(v, kMapOffset); |
1062 // Handle object body | 1030 // Handle object body |
1063 Map* m = map(); | 1031 Map* m = map(); |
1064 IterateBody(m->instance_type(), SizeFromMap(m), v); | 1032 IterateBody(m->instance_type(), SizeFromMap(m), v); |
1065 } | 1033 } |
1066 | 1034 |
1067 | 1035 |
1068 void HeapObject::IterateBody(InstanceType type, int object_size, | 1036 void HeapObject::IterateBody(InstanceType type, int object_size, |
(...skipping 22 matching lines...) Expand all Loading... |
1091 | 1059 |
1092 switch (type) { | 1060 switch (type) { |
1093 case FIXED_ARRAY_TYPE: | 1061 case FIXED_ARRAY_TYPE: |
1094 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); | 1062 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); |
1095 break; | 1063 break; |
1096 case JS_OBJECT_TYPE: | 1064 case JS_OBJECT_TYPE: |
1097 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: | 1065 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: |
1098 case JS_VALUE_TYPE: | 1066 case JS_VALUE_TYPE: |
1099 case JS_ARRAY_TYPE: | 1067 case JS_ARRAY_TYPE: |
1100 case JS_REGEXP_TYPE: | 1068 case JS_REGEXP_TYPE: |
1101 case JS_FUNCTION_TYPE: | |
1102 case JS_GLOBAL_PROXY_TYPE: | 1069 case JS_GLOBAL_PROXY_TYPE: |
1103 case JS_GLOBAL_OBJECT_TYPE: | 1070 case JS_GLOBAL_OBJECT_TYPE: |
1104 case JS_BUILTINS_OBJECT_TYPE: | 1071 case JS_BUILTINS_OBJECT_TYPE: |
1105 JSObject::BodyDescriptor::IterateBody(this, object_size, v); | 1072 JSObject::BodyDescriptor::IterateBody(this, object_size, v); |
1106 break; | 1073 break; |
| 1074 case JS_FUNCTION_TYPE: |
| 1075 reinterpret_cast<JSFunction*>(this) |
| 1076 ->JSFunctionIterateBody(object_size, v); |
| 1077 break; |
1107 case ODDBALL_TYPE: | 1078 case ODDBALL_TYPE: |
1108 Oddball::BodyDescriptor::IterateBody(this, v); | 1079 Oddball::BodyDescriptor::IterateBody(this, v); |
1109 break; | 1080 break; |
1110 case PROXY_TYPE: | 1081 case PROXY_TYPE: |
1111 reinterpret_cast<Proxy*>(this)->ProxyIterateBody(v); | 1082 reinterpret_cast<Proxy*>(this)->ProxyIterateBody(v); |
1112 break; | 1083 break; |
1113 case MAP_TYPE: | 1084 case MAP_TYPE: |
1114 Map::BodyDescriptor::IterateBody(this, v); | 1085 Map::BodyDescriptor::IterateBody(this, v); |
1115 break; | 1086 break; |
1116 case CODE_TYPE: | 1087 case CODE_TYPE: |
(...skipping 24 matching lines...) Expand all Loading... |
1141 #undef MAKE_STRUCT_CASE | 1112 #undef MAKE_STRUCT_CASE |
1142 StructBodyDescriptor::IterateBody(this, object_size, v); | 1113 StructBodyDescriptor::IterateBody(this, object_size, v); |
1143 break; | 1114 break; |
1144 default: | 1115 default: |
1145 PrintF("Unknown type: %d\n", type); | 1116 PrintF("Unknown type: %d\n", type); |
1146 UNREACHABLE(); | 1117 UNREACHABLE(); |
1147 } | 1118 } |
1148 } | 1119 } |
1149 | 1120 |
1150 | 1121 |
1151 void HeapObject::IterateStructBody(int object_size, ObjectVisitor* v) { | |
1152 IteratePointers(v, HeapObject::kHeaderSize, object_size); | |
1153 } | |
1154 | |
1155 | |
1156 Object* HeapNumber::HeapNumberToBoolean() { | 1122 Object* HeapNumber::HeapNumberToBoolean() { |
1157 // NaN, +0, and -0 should return the false object | 1123 // NaN, +0, and -0 should return the false object |
1158 #if __BYTE_ORDER == __LITTLE_ENDIAN | 1124 #if __BYTE_ORDER == __LITTLE_ENDIAN |
1159 union IeeeDoubleLittleEndianArchType u; | 1125 union IeeeDoubleLittleEndianArchType u; |
1160 #elif __BYTE_ORDER == __BIG_ENDIAN | 1126 #elif __BYTE_ORDER == __BIG_ENDIAN |
1161 union IeeeDoubleBigEndianArchType u; | 1127 union IeeeDoubleBigEndianArchType u; |
1162 #endif | 1128 #endif |
1163 u.d = value(); | 1129 u.d = value(); |
1164 if (u.bits.exp == 2047) { | 1130 if (u.bits.exp == 2047) { |
1165 // Detect NaN for IEEE double precision floating point. | 1131 // Detect NaN for IEEE double precision floating point. |
(...skipping 3852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5018 ASSERT(target->prototype() == this || | 4984 ASSERT(target->prototype() == this || |
5019 target->prototype() == real_prototype); | 4985 target->prototype() == real_prototype); |
5020 // Getter prototype() is read-only, set_prototype() has side effects. | 4986 // Getter prototype() is read-only, set_prototype() has side effects. |
5021 *RawField(target, Map::kPrototypeOffset) = real_prototype; | 4987 *RawField(target, Map::kPrototypeOffset) = real_prototype; |
5022 } | 4988 } |
5023 } | 4989 } |
5024 } | 4990 } |
5025 } | 4991 } |
5026 | 4992 |
5027 | 4993 |
| 4994 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { |
| 4995 // Iterate over all fields in the body but take care in dealing with |
| 4996 // the code entry. |
| 4997 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); |
| 4998 v->VisitCodeEntry(this->address() + kCodeEntryOffset); |
| 4999 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); |
| 5000 } |
| 5001 |
| 5002 |
5028 Object* JSFunction::SetInstancePrototype(Object* value) { | 5003 Object* JSFunction::SetInstancePrototype(Object* value) { |
5029 ASSERT(value->IsJSObject()); | 5004 ASSERT(value->IsJSObject()); |
5030 | 5005 |
5031 if (has_initial_map()) { | 5006 if (has_initial_map()) { |
5032 initial_map()->set_prototype(value); | 5007 initial_map()->set_prototype(value); |
5033 } else { | 5008 } else { |
5034 // Put the value in the initial map field until an initial map is | 5009 // Put the value in the initial map field until an initial map is |
5035 // needed. At that point, a new initial map is created and the | 5010 // needed. At that point, a new initial map is created and the |
5036 // prototype is put into the initial map where it belongs. | 5011 // prototype is put into the initial map where it belongs. |
5037 set_prototype_or_initial_map(value); | 5012 set_prototype_or_initial_map(value); |
5038 } | 5013 } |
5039 Heap::ClearInstanceofCache(); | 5014 Heap::ClearInstanceofCache(); |
5040 return value; | 5015 return value; |
5041 } | 5016 } |
5042 | 5017 |
5043 | 5018 |
5044 | |
5045 Object* JSFunction::SetPrototype(Object* value) { | 5019 Object* JSFunction::SetPrototype(Object* value) { |
5046 ASSERT(should_have_prototype()); | 5020 ASSERT(should_have_prototype()); |
5047 Object* construct_prototype = value; | 5021 Object* construct_prototype = value; |
5048 | 5022 |
5049 // If the value is not a JSObject, store the value in the map's | 5023 // If the value is not a JSObject, store the value in the map's |
5050 // constructor field so it can be accessed. Also, set the prototype | 5024 // constructor field so it can be accessed. Also, set the prototype |
5051 // used for constructing objects to the original object prototype. | 5025 // used for constructing objects to the original object prototype. |
5052 // See ECMA-262 13.2.2. | 5026 // See ECMA-262 13.2.2. |
5053 if (!value->IsJSObject()) { | 5027 if (!value->IsJSObject()) { |
5054 // Copy the map so this does not affect unrelated functions. | 5028 // Copy the map so this does not affect unrelated functions. |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5262 | 5236 |
5263 void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) { | 5237 void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) { |
5264 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 5238 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
5265 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 5239 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
5266 Object* old_target = target; | 5240 Object* old_target = target; |
5267 VisitPointer(&target); | 5241 VisitPointer(&target); |
5268 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. | 5242 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
5269 } | 5243 } |
5270 | 5244 |
5271 | 5245 |
| 5246 void ObjectVisitor::VisitCodeEntry(Address entry_address) { |
| 5247 Object* code = Code::GetObjectFromEntryAddress(entry_address); |
| 5248 Object* old_code = code; |
| 5249 VisitPointer(&code); |
| 5250 if (code != old_code) { |
| 5251 Memory::Address_at(entry_address) = reinterpret_cast<Code*>(code)->entry(); |
| 5252 } |
| 5253 } |
| 5254 |
| 5255 |
5272 void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { | 5256 void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { |
5273 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 5257 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && |
5274 rinfo->IsPatchedReturnSequence()) || | 5258 rinfo->IsPatchedReturnSequence()) || |
5275 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 5259 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
5276 rinfo->IsPatchedDebugBreakSlotSequence())); | 5260 rinfo->IsPatchedDebugBreakSlotSequence())); |
5277 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 5261 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
5278 Object* old_target = target; | 5262 Object* old_target = target; |
5279 VisitPointer(&target); | 5263 VisitPointer(&target); |
5280 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. | 5264 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
5281 } | 5265 } |
(...skipping 3491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8773 if (break_point_objects()->IsUndefined()) return 0; | 8757 if (break_point_objects()->IsUndefined()) return 0; |
8774 // Single beak point. | 8758 // Single beak point. |
8775 if (!break_point_objects()->IsFixedArray()) return 1; | 8759 if (!break_point_objects()->IsFixedArray()) return 1; |
8776 // Multiple break points. | 8760 // Multiple break points. |
8777 return FixedArray::cast(break_point_objects())->length(); | 8761 return FixedArray::cast(break_point_objects())->length(); |
8778 } | 8762 } |
8779 #endif | 8763 #endif |
8780 | 8764 |
8781 | 8765 |
8782 } } // namespace v8::internal | 8766 } } // namespace v8::internal |
OLD | NEW |