| 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 |