 Chromium Code Reviews
 Chromium Code Reviews Issue 6542047:
  Basic implementation of incremental marking.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
    
  
    Issue 6542047:
  Basic implementation of incremental marking.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/experimental/gc| OLD | NEW | 
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 26 matching lines...) Expand all Loading... | |
| 37 | 37 | 
| 38 #include "objects.h" | 38 #include "objects.h" | 
| 39 #include "contexts.h" | 39 #include "contexts.h" | 
| 40 #include "conversions-inl.h" | 40 #include "conversions-inl.h" | 
| 41 #include "heap.h" | 41 #include "heap.h" | 
| 42 #include "memory.h" | 42 #include "memory.h" | 
| 43 #include "property.h" | 43 #include "property.h" | 
| 44 #include "spaces.h" | 44 #include "spaces.h" | 
| 45 #include "store-buffer.h" | 45 #include "store-buffer.h" | 
| 46 | 46 | 
| 47 #include "incremental-marking.h" | |
| 48 | |
| 47 namespace v8 { | 49 namespace v8 { | 
| 48 namespace internal { | 50 namespace internal { | 
| 49 | 51 | 
| 50 PropertyDetails::PropertyDetails(Smi* smi) { | 52 PropertyDetails::PropertyDetails(Smi* smi) { | 
| 51 value_ = smi->value(); | 53 value_ = smi->value(); | 
| 52 } | 54 } | 
| 53 | 55 | 
| 54 | 56 | 
| 55 Smi* PropertyDetails::AsSmi() { | 57 Smi* PropertyDetails::AsSmi() { | 
| 56 return Smi::FromInt(value_); | 58 return Smi::FromInt(value_); | 
| (...skipping 15 matching lines...) Expand all Loading... | |
| 72 | 74 | 
| 73 #define INT_ACCESSORS(holder, name, offset) \ | 75 #define INT_ACCESSORS(holder, name, offset) \ | 
| 74 int holder::name() { return READ_INT_FIELD(this, offset); } \ | 76 int holder::name() { return READ_INT_FIELD(this, offset); } \ | 
| 75 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } | 77 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } | 
| 76 | 78 | 
| 77 | 79 | 
| 78 #define ACCESSORS(holder, name, type, offset) \ | 80 #define ACCESSORS(holder, name, type, offset) \ | 
| 79 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \ | 81 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \ | 
| 80 void holder::set_##name(type* value, WriteBarrierMode mode) { \ | 82 void holder::set_##name(type* value, WriteBarrierMode mode) { \ | 
| 81 WRITE_FIELD(this, offset, value); \ | 83 WRITE_FIELD(this, offset, value); \ | 
| 82 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \ | 84 WRITE_BARRIER(this, offset, value); \ | 
| 
Erik Corry
2011/02/22 12:27:19
Indentation of backslashes is now wrong.
 
Vyacheslav Egorov (Chromium)
2011/02/23 14:31:46
Done.
 | |
| 83 } | 85 } | 
| 84 | 86 | 
| 85 | 87 | 
| 86 #define SMI_ACCESSORS(holder, name, offset) \ | 88 #define SMI_ACCESSORS(holder, name, offset) \ | 
| 87 int holder::name() { \ | 89 int holder::name() { \ | 
| 88 Object* value = READ_FIELD(this, offset); \ | 90 Object* value = READ_FIELD(this, offset); \ | 
| 89 return Smi::cast(value)->value(); \ | 91 return Smi::cast(value)->value(); \ | 
| 90 } \ | 92 } \ | 
| 91 void holder::set_##name(int value) { \ | 93 void holder::set_##name(int value) { \ | 
| 92 WRITE_FIELD(this, offset, Smi::FromInt(value)); \ | 94 WRITE_FIELD(this, offset, Smi::FromInt(value)); \ | 
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 | 798 | 
| 797 #define FIELD_ADDR(p, offset) \ | 799 #define FIELD_ADDR(p, offset) \ | 
| 798 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) | 800 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) | 
| 799 | 801 | 
| 800 #define READ_FIELD(p, offset) \ | 802 #define READ_FIELD(p, offset) \ | 
| 801 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset))) | 803 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset))) | 
| 802 | 804 | 
| 803 #define WRITE_FIELD(p, offset, value) \ | 805 #define WRITE_FIELD(p, offset, value) \ | 
| 804 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value) | 806 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value) | 
| 805 | 807 | 
| 806 | 808 #define WRITE_BARRIER(object, offset, value) \ | 
| 807 #define WRITE_BARRIER(object, offset) \ | 809 IncrementalMarking::RecordWrite(object, value); \ | 
| 808 Heap::RecordWrite(object->address(), offset); | 810 Heap::RecordWrite(object->address(), offset); | 
| 809 | 811 | 
| 810 // CONDITIONAL_WRITE_BARRIER must be issued after the actual | |
| 811 // write due to the assert validating the written value. | |
| 812 #define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \ | |
| 813 if (mode == UPDATE_WRITE_BARRIER) { \ | |
| 814 Heap::RecordWrite(object->address(), offset); \ | |
| 815 } else { \ | |
| 816 ASSERT(mode == SKIP_WRITE_BARRIER); \ | |
| 817 ASSERT(Heap::InNewSpace(object) || \ | |
| 818 !Heap::InNewSpace(READ_FIELD(object, offset)) || \ | |
| 819 StoreBuffer::CellIsInStoreBuffer(object->address() + offset)); \ | |
| 820 } | |
| 821 | |
| 822 #define READ_DOUBLE_FIELD(p, offset) \ | 812 #define READ_DOUBLE_FIELD(p, offset) \ | 
| 823 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset))) | 813 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset))) | 
| 824 | 814 | 
| 825 #define WRITE_DOUBLE_FIELD(p, offset, value) \ | 815 #define WRITE_DOUBLE_FIELD(p, offset, value) \ | 
| 826 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value) | 816 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value) | 
| 827 | 817 | 
| 828 #define READ_INT_FIELD(p, offset) \ | 818 #define READ_INT_FIELD(p, offset) \ | 
| 829 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset))) | 819 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset))) | 
| 830 | 820 | 
| 831 #define WRITE_INT_FIELD(p, offset, value) \ | 821 #define WRITE_INT_FIELD(p, offset, value) \ | 
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1009 #endif | 999 #endif | 
| 1010 | 1000 | 
| 1011 | 1001 | 
| 1012 Map* HeapObject::map() { | 1002 Map* HeapObject::map() { | 
| 1013 return map_word().ToMap(); | 1003 return map_word().ToMap(); | 
| 1014 } | 1004 } | 
| 1015 | 1005 | 
| 1016 | 1006 | 
| 1017 void HeapObject::set_map(Map* value) { | 1007 void HeapObject::set_map(Map* value) { | 
| 1018 set_map_word(MapWord::FromMap(value)); | 1008 set_map_word(MapWord::FromMap(value)); | 
| 1009 IncrementalMarking::RecordWrite(this, value); | |
| 1019 } | 1010 } | 
| 1020 | 1011 | 
| 1021 | 1012 | 
| 1022 MapWord HeapObject::map_word() { | 1013 MapWord HeapObject::map_word() { | 
| 1023 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset))); | 1014 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset))); | 
| 1024 } | 1015 } | 
| 1025 | 1016 | 
| 1026 | 1017 | 
| 1027 void HeapObject::set_map_word(MapWord map_word) { | 1018 void HeapObject::set_map_word(MapWord map_word) { | 
| 1028 // WRITE_FIELD does not invoke write barrier, but there is no need | 1019 // WRITE_FIELD does not invoke write barrier, but there is no need | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1092 | 1083 | 
| 1093 | 1084 | 
| 1094 void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) { | 1085 void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) { | 
| 1095 ASSERT(map()->has_fast_elements() == | 1086 ASSERT(map()->has_fast_elements() == | 
| 1096 (value->map() == Heap::fixed_array_map() || | 1087 (value->map() == Heap::fixed_array_map() || | 
| 1097 value->map() == Heap::fixed_cow_array_map())); | 1088 value->map() == Heap::fixed_cow_array_map())); | 
| 1098 // In the assert below Dictionary is covered under FixedArray. | 1089 // In the assert below Dictionary is covered under FixedArray. | 
| 1099 ASSERT(value->IsFixedArray() || value->IsPixelArray() || | 1090 ASSERT(value->IsFixedArray() || value->IsPixelArray() || | 
| 1100 value->IsExternalArray()); | 1091 value->IsExternalArray()); | 
| 1101 WRITE_FIELD(this, kElementsOffset, value); | 1092 WRITE_FIELD(this, kElementsOffset, value); | 
| 1102 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode); | 1093 WRITE_BARRIER(this, kElementsOffset, value); | 
| 1103 } | 1094 } | 
| 1104 | 1095 | 
| 1105 | 1096 | 
| 1106 void JSObject::initialize_properties() { | 1097 void JSObject::initialize_properties() { | 
| 1107 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array())); | 1098 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array())); | 
| 1108 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array()); | 1099 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array()); | 
| 1109 } | 1100 } | 
| 1110 | 1101 | 
| 1111 | 1102 | 
| 1112 void JSObject::initialize_elements() { | 1103 void JSObject::initialize_elements() { | 
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1133 | 1124 | 
| 1134 Object* JSGlobalPropertyCell::value() { | 1125 Object* JSGlobalPropertyCell::value() { | 
| 1135 return READ_FIELD(this, kValueOffset); | 1126 return READ_FIELD(this, kValueOffset); | 
| 1136 } | 1127 } | 
| 1137 | 1128 | 
| 1138 | 1129 | 
| 1139 void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) { | 1130 void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) { | 
| 1140 // The write barrier is not used for global property cells. | 1131 // The write barrier is not used for global property cells. | 
| 1141 ASSERT(!val->IsJSGlobalPropertyCell()); | 1132 ASSERT(!val->IsJSGlobalPropertyCell()); | 
| 1142 WRITE_FIELD(this, kValueOffset, val); | 1133 WRITE_FIELD(this, kValueOffset, val); | 
| 1134 IncrementalMarking::RecordWrite(this, val); | |
| 1143 } | 1135 } | 
| 1144 | 1136 | 
| 1145 | 1137 | 
| 1146 int JSObject::GetHeaderSize() { | 1138 int JSObject::GetHeaderSize() { | 
| 1147 InstanceType type = map()->instance_type(); | 1139 InstanceType type = map()->instance_type(); | 
| 1148 // Check for the most common kind of JavaScript object before | 1140 // Check for the most common kind of JavaScript object before | 
| 1149 // falling into the generic switch. This speeds up the internal | 1141 // falling into the generic switch. This speeds up the internal | 
| 1150 // field operations considerably on average. | 1142 // field operations considerably on average. | 
| 1151 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize; | 1143 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize; | 
| 1152 switch (type) { | 1144 switch (type) { | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1193 } | 1185 } | 
| 1194 | 1186 | 
| 1195 | 1187 | 
| 1196 void JSObject::SetInternalField(int index, Object* value) { | 1188 void JSObject::SetInternalField(int index, Object* value) { | 
| 1197 ASSERT(index < GetInternalFieldCount() && index >= 0); | 1189 ASSERT(index < GetInternalFieldCount() && index >= 0); | 
| 1198 // Internal objects do follow immediately after the header, whereas in-object | 1190 // Internal objects do follow immediately after the header, whereas in-object | 
| 1199 // properties are at the end of the object. Therefore there is no need | 1191 // properties are at the end of the object. Therefore there is no need | 
| 1200 // to adjust the index here. | 1192 // to adjust the index here. | 
| 1201 int offset = GetHeaderSize() + (kPointerSize * index); | 1193 int offset = GetHeaderSize() + (kPointerSize * index); | 
| 1202 WRITE_FIELD(this, offset, value); | 1194 WRITE_FIELD(this, offset, value); | 
| 1203 WRITE_BARRIER(this, offset); | 1195 WRITE_BARRIER(this, offset, value); | 
| 1204 } | 1196 } | 
| 1205 | 1197 | 
| 1206 | 1198 | 
| 1207 // Access fast-case object properties at index. The use of these routines | 1199 // Access fast-case object properties at index. The use of these routines | 
| 1208 // is needed to correctly distinguish between properties stored in-object and | 1200 // is needed to correctly distinguish between properties stored in-object and | 
| 1209 // properties stored in the properties array. | 1201 // properties stored in the properties array. | 
| 1210 Object* JSObject::FastPropertyAt(int index) { | 1202 Object* JSObject::FastPropertyAt(int index) { | 
| 1211 // Adjust for the number of properties stored in the object. | 1203 // Adjust for the number of properties stored in the object. | 
| 1212 index -= map()->inobject_properties(); | 1204 index -= map()->inobject_properties(); | 
| 1213 if (index < 0) { | 1205 if (index < 0) { | 
| 1214 int offset = map()->instance_size() + (index * kPointerSize); | 1206 int offset = map()->instance_size() + (index * kPointerSize); | 
| 1215 return READ_FIELD(this, offset); | 1207 return READ_FIELD(this, offset); | 
| 1216 } else { | 1208 } else { | 
| 1217 ASSERT(index < properties()->length()); | 1209 ASSERT(index < properties()->length()); | 
| 1218 return properties()->get(index); | 1210 return properties()->get(index); | 
| 1219 } | 1211 } | 
| 1220 } | 1212 } | 
| 1221 | 1213 | 
| 1222 | 1214 | 
| 1223 Object* JSObject::FastPropertyAtPut(int index, Object* value) { | 1215 Object* JSObject::FastPropertyAtPut(int index, Object* value) { | 
| 1224 // Adjust for the number of properties stored in the object. | 1216 // Adjust for the number of properties stored in the object. | 
| 1225 index -= map()->inobject_properties(); | 1217 index -= map()->inobject_properties(); | 
| 1226 if (index < 0) { | 1218 if (index < 0) { | 
| 1227 int offset = map()->instance_size() + (index * kPointerSize); | 1219 int offset = map()->instance_size() + (index * kPointerSize); | 
| 1228 WRITE_FIELD(this, offset, value); | 1220 WRITE_FIELD(this, offset, value); | 
| 1229 WRITE_BARRIER(this, offset); | 1221 WRITE_BARRIER(this, offset, value); | 
| 1230 } else { | 1222 } else { | 
| 1231 ASSERT(index < properties()->length()); | 1223 ASSERT(index < properties()->length()); | 
| 1232 properties()->set(index, value); | 1224 properties()->set(index, value); | 
| 1233 } | 1225 } | 
| 1234 return value; | 1226 return value; | 
| 1235 } | 1227 } | 
| 1236 | 1228 | 
| 1237 | 1229 | 
| 1238 Object* JSObject::InObjectPropertyAt(int index) { | 1230 Object* JSObject::InObjectPropertyAt(int index) { | 
| 1239 // Adjust for the number of properties stored in the object. | 1231 // Adjust for the number of properties stored in the object. | 
| 1240 index -= map()->inobject_properties(); | 1232 index -= map()->inobject_properties(); | 
| 1241 ASSERT(index < 0); | 1233 ASSERT(index < 0); | 
| 1242 int offset = map()->instance_size() + (index * kPointerSize); | 1234 int offset = map()->instance_size() + (index * kPointerSize); | 
| 1243 return READ_FIELD(this, offset); | 1235 return READ_FIELD(this, offset); | 
| 1244 } | 1236 } | 
| 1245 | 1237 | 
| 1246 | 1238 | 
| 1247 Object* JSObject::InObjectPropertyAtPut(int index, | 1239 Object* JSObject::InObjectPropertyAtPut(int index, | 
| 1248 Object* value, | 1240 Object* value, | 
| 1249 WriteBarrierMode mode) { | 1241 WriteBarrierMode mode) { | 
| 1250 // Adjust for the number of properties stored in the object. | 1242 // Adjust for the number of properties stored in the object. | 
| 1251 index -= map()->inobject_properties(); | 1243 index -= map()->inobject_properties(); | 
| 1252 ASSERT(index < 0); | 1244 ASSERT(index < 0); | 
| 1253 int offset = map()->instance_size() + (index * kPointerSize); | 1245 int offset = map()->instance_size() + (index * kPointerSize); | 
| 1254 WRITE_FIELD(this, offset, value); | 1246 WRITE_FIELD(this, offset, value); | 
| 1255 CONDITIONAL_WRITE_BARRIER(this, offset, mode); | 1247 WRITE_BARRIER(this, offset, value); | 
| 1256 return value; | 1248 return value; | 
| 1257 } | 1249 } | 
| 1258 | 1250 | 
| 1259 | 1251 | 
| 1260 | 1252 | 
| 1261 void JSObject::InitializeBody(int object_size, Object* value) { | 1253 void JSObject::InitializeBody(int object_size, Object* value) { | 
| 1262 ASSERT(!value->IsHeapObject() || !Heap::InNewSpace(value)); | 1254 ASSERT(!value->IsHeapObject() || !Heap::InNewSpace(value)); | 
| 1263 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) { | 1255 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) { | 
| 1264 WRITE_FIELD(this, offset, value); | 1256 WRITE_FIELD(this, offset, value); | 
| 1265 } | 1257 } | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1333 int offset = kHeaderSize + index * kPointerSize; | 1325 int offset = kHeaderSize + index * kPointerSize; | 
| 1334 WRITE_FIELD(this, offset, value); | 1326 WRITE_FIELD(this, offset, value); | 
| 1335 } | 1327 } | 
| 1336 | 1328 | 
| 1337 | 1329 | 
| 1338 void FixedArray::set(int index, Object* value) { | 1330 void FixedArray::set(int index, Object* value) { | 
| 1339 ASSERT(map() != Heap::fixed_cow_array_map()); | 1331 ASSERT(map() != Heap::fixed_cow_array_map()); | 
| 1340 ASSERT(index >= 0 && index < this->length()); | 1332 ASSERT(index >= 0 && index < this->length()); | 
| 1341 int offset = kHeaderSize + index * kPointerSize; | 1333 int offset = kHeaderSize + index * kPointerSize; | 
| 1342 WRITE_FIELD(this, offset, value); | 1334 WRITE_FIELD(this, offset, value); | 
| 1343 WRITE_BARRIER(this, offset); | 1335 WRITE_BARRIER(this, offset, value); | 
| 1344 } | 1336 } | 
| 1345 | 1337 | 
| 1346 | 1338 | 
| 1347 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) { | 1339 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) { | 
| 1348 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER; | 1340 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER; | 
| 1349 return UPDATE_WRITE_BARRIER; | 1341 return UPDATE_WRITE_BARRIER; | 
| 1350 } | 1342 } | 
| 1351 | 1343 | 
| 1352 | 1344 | 
| 1353 void FixedArray::set(int index, | 1345 void FixedArray::set(int index, | 
| 1354 Object* value, | 1346 Object* value, | 
| 1355 WriteBarrierMode mode) { | 1347 WriteBarrierMode mode) { | 
| 1356 ASSERT(map() != Heap::fixed_cow_array_map()); | 1348 ASSERT(map() != Heap::fixed_cow_array_map()); | 
| 1357 ASSERT(index >= 0 && index < this->length()); | 1349 ASSERT(index >= 0 && index < this->length()); | 
| 1358 int offset = kHeaderSize + index * kPointerSize; | 1350 int offset = kHeaderSize + index * kPointerSize; | 
| 1359 WRITE_FIELD(this, offset, value); | 1351 WRITE_FIELD(this, offset, value); | 
| 1360 CONDITIONAL_WRITE_BARRIER(this, offset, mode); | 1352 WRITE_BARRIER(this, offset, value); | 
| 1361 } | 1353 } | 
| 1362 | 1354 | 
| 1363 | 1355 | 
| 1364 void FixedArray::fast_set(FixedArray* array, int index, Object* value) { | 1356 void FixedArray::fast_set(FixedArray* array, int index, Object* value) { | 
| 1365 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map()); | 1357 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map()); | 
| 1366 ASSERT(index >= 0 && index < array->length()); | 1358 ASSERT(index >= 0 && index < array->length()); | 
| 1367 ASSERT(!Heap::InNewSpace(value)); | 1359 ASSERT(!Heap::InNewSpace(value)); | 
| 1368 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value); | 1360 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value); | 
| 1361 IncrementalMarking::RecordWrite(array, value); | |
| 1369 } | 1362 } | 
| 1370 | 1363 | 
| 1371 | 1364 | 
| 1372 void FixedArray::set_undefined(int index) { | 1365 void FixedArray::set_undefined(int index) { | 
| 1373 ASSERT(map() != Heap::fixed_cow_array_map()); | 1366 ASSERT(map() != Heap::fixed_cow_array_map()); | 
| 1374 ASSERT(index >= 0 && index < this->length()); | 1367 ASSERT(index >= 0 && index < this->length()); | 
| 1375 ASSERT(!Heap::InNewSpace(Heap::undefined_value())); | 1368 ASSERT(!Heap::InNewSpace(Heap::undefined_value())); | 
| 1376 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, | 1369 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, | 
| 1377 Heap::undefined_value()); | 1370 Heap::undefined_value()); | 
| 1378 } | 1371 } | 
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1399 int offset = kHeaderSize + index * kPointerSize; | 1392 int offset = kHeaderSize + index * kPointerSize; | 
| 1400 WRITE_FIELD(this, offset, value); | 1393 WRITE_FIELD(this, offset, value); | 
| 1401 } | 1394 } | 
| 1402 | 1395 | 
| 1403 | 1396 | 
| 1404 void FixedArray::set_unchecked(int index, | 1397 void FixedArray::set_unchecked(int index, | 
| 1405 Object* value, | 1398 Object* value, | 
| 1406 WriteBarrierMode mode) { | 1399 WriteBarrierMode mode) { | 
| 1407 int offset = kHeaderSize + index * kPointerSize; | 1400 int offset = kHeaderSize + index * kPointerSize; | 
| 1408 WRITE_FIELD(this, offset, value); | 1401 WRITE_FIELD(this, offset, value); | 
| 1409 CONDITIONAL_WRITE_BARRIER(this, offset, mode); | 1402 WRITE_BARRIER(this, offset, value); | 
| 1410 } | 1403 } | 
| 1411 | 1404 | 
| 1412 | 1405 | 
| 1413 void FixedArray::set_null_unchecked(int index) { | 1406 void FixedArray::set_null_unchecked(int index) { | 
| 1414 ASSERT(index >= 0 && index < this->length()); | 1407 ASSERT(index >= 0 && index < this->length()); | 
| 1415 ASSERT(!Heap::InNewSpace(Heap::null_value())); | 1408 ASSERT(!Heap::InNewSpace(Heap::null_value())); | 
| 1416 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value()); | 1409 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value()); | 
| 1417 } | 1410 } | 
| 1418 | 1411 | 
| 1419 | 1412 | 
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1810 } | 1803 } | 
| 1811 | 1804 | 
| 1812 | 1805 | 
| 1813 Object* ConsString::unchecked_first() { | 1806 Object* ConsString::unchecked_first() { | 
| 1814 return READ_FIELD(this, kFirstOffset); | 1807 return READ_FIELD(this, kFirstOffset); | 
| 1815 } | 1808 } | 
| 1816 | 1809 | 
| 1817 | 1810 | 
| 1818 void ConsString::set_first(String* value, WriteBarrierMode mode) { | 1811 void ConsString::set_first(String* value, WriteBarrierMode mode) { | 
| 1819 WRITE_FIELD(this, kFirstOffset, value); | 1812 WRITE_FIELD(this, kFirstOffset, value); | 
| 1820 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode); | 1813 WRITE_BARRIER(this, kFirstOffset, value); | 
| 1821 } | 1814 } | 
| 1822 | 1815 | 
| 1823 | 1816 | 
| 1824 String* ConsString::second() { | 1817 String* ConsString::second() { | 
| 1825 return String::cast(READ_FIELD(this, kSecondOffset)); | 1818 return String::cast(READ_FIELD(this, kSecondOffset)); | 
| 1826 } | 1819 } | 
| 1827 | 1820 | 
| 1828 | 1821 | 
| 1829 Object* ConsString::unchecked_second() { | 1822 Object* ConsString::unchecked_second() { | 
| 1830 return READ_FIELD(this, kSecondOffset); | 1823 return READ_FIELD(this, kSecondOffset); | 
| 1831 } | 1824 } | 
| 1832 | 1825 | 
| 1833 | 1826 | 
| 1834 void ConsString::set_second(String* value, WriteBarrierMode mode) { | 1827 void ConsString::set_second(String* value, WriteBarrierMode mode) { | 
| 1835 WRITE_FIELD(this, kSecondOffset, value); | 1828 WRITE_FIELD(this, kSecondOffset, value); | 
| 1836 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode); | 1829 WRITE_BARRIER(this, kSecondOffset, value); | 
| 1837 } | 1830 } | 
| 1838 | 1831 | 
| 1839 | 1832 | 
| 1840 ExternalAsciiString::Resource* ExternalAsciiString::resource() { | 1833 ExternalAsciiString::Resource* ExternalAsciiString::resource() { | 
| 1841 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); | 1834 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); | 
| 1842 } | 1835 } | 
| 1843 | 1836 | 
| 1844 | 1837 | 
| 1845 void ExternalAsciiString::set_resource( | 1838 void ExternalAsciiString::set_resource( | 
| 1846 ExternalAsciiString::Resource* resource) { | 1839 ExternalAsciiString::Resource* resource) { | 
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2586 | 2579 | 
| 2587 | 2580 | 
| 2588 Object* Map::prototype() { | 2581 Object* Map::prototype() { | 
| 2589 return READ_FIELD(this, kPrototypeOffset); | 2582 return READ_FIELD(this, kPrototypeOffset); | 
| 2590 } | 2583 } | 
| 2591 | 2584 | 
| 2592 | 2585 | 
| 2593 void Map::set_prototype(Object* value, WriteBarrierMode mode) { | 2586 void Map::set_prototype(Object* value, WriteBarrierMode mode) { | 
| 2594 ASSERT(value->IsNull() || value->IsJSObject()); | 2587 ASSERT(value->IsNull() || value->IsJSObject()); | 
| 2595 WRITE_FIELD(this, kPrototypeOffset, value); | 2588 WRITE_FIELD(this, kPrototypeOffset, value); | 
| 2596 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode); | 2589 WRITE_BARRIER(this, kPrototypeOffset, value); | 
| 2597 } | 2590 } | 
| 2598 | 2591 | 
| 2599 | 2592 | 
| 2600 MaybeObject* Map::GetFastElementsMap() { | 2593 MaybeObject* Map::GetFastElementsMap() { | 
| 2601 if (has_fast_elements()) return this; | 2594 if (has_fast_elements()) return this; | 
| 2602 Object* obj; | 2595 Object* obj; | 
| 2603 { MaybeObject* maybe_obj = CopyDropTransitions(); | 2596 { MaybeObject* maybe_obj = CopyDropTransitions(); | 
| 2604 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2597 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 
| 2605 } | 2598 } | 
| 2606 Map* new_map = Map::cast(obj); | 2599 Map* new_map = Map::cast(obj); | 
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2936 } | 2929 } | 
| 2937 | 2930 | 
| 2938 | 2931 | 
| 2939 Code* SharedFunctionInfo::unchecked_code() { | 2932 Code* SharedFunctionInfo::unchecked_code() { | 
| 2940 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset)); | 2933 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset)); | 
| 2941 } | 2934 } | 
| 2942 | 2935 | 
| 2943 | 2936 | 
| 2944 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) { | 2937 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) { | 
| 2945 WRITE_FIELD(this, kCodeOffset, value); | 2938 WRITE_FIELD(this, kCodeOffset, value); | 
| 2946 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode); | 2939 WRITE_BARRIER(this, kCodeOffset, value); | 
| 2947 } | 2940 } | 
| 2948 | 2941 | 
| 2949 | 2942 | 
| 2950 SerializedScopeInfo* SharedFunctionInfo::scope_info() { | 2943 SerializedScopeInfo* SharedFunctionInfo::scope_info() { | 
| 2951 return reinterpret_cast<SerializedScopeInfo*>( | 2944 return reinterpret_cast<SerializedScopeInfo*>( | 
| 2952 READ_FIELD(this, kScopeInfoOffset)); | 2945 READ_FIELD(this, kScopeInfoOffset)); | 
| 2953 } | 2946 } | 
| 2954 | 2947 | 
| 2955 | 2948 | 
| 2956 void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value, | 2949 void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value, | 
| 2957 WriteBarrierMode mode) { | 2950 WriteBarrierMode mode) { | 
| 2958 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value)); | 2951 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value)); | 
| 2959 CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode); | 2952 WRITE_BARRIER(this, kScopeInfoOffset, reinterpret_cast<Object*>(value)); | 
| 2960 } | 2953 } | 
| 2961 | 2954 | 
| 2962 | 2955 | 
| 2963 Smi* SharedFunctionInfo::deopt_counter() { | 2956 Smi* SharedFunctionInfo::deopt_counter() { | 
| 2964 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset)); | 2957 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset)); | 
| 2965 } | 2958 } | 
| 2966 | 2959 | 
| 2967 | 2960 | 
| 2968 void SharedFunctionInfo::set_deopt_counter(Smi* value) { | 2961 void SharedFunctionInfo::set_deopt_counter(Smi* value) { | 
| 2969 WRITE_FIELD(this, kDeoptCounterOffset, value); | 2962 WRITE_FIELD(this, kDeoptCounterOffset, value); | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3044 return reinterpret_cast<Code*>( | 3037 return reinterpret_cast<Code*>( | 
| 3045 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset))); | 3038 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset))); | 
| 3046 } | 3039 } | 
| 3047 | 3040 | 
| 3048 | 3041 | 
| 3049 void JSFunction::set_code(Code* value) { | 3042 void JSFunction::set_code(Code* value) { | 
| 3050 // Skip the write barrier because code is never in new space. | 3043 // Skip the write barrier because code is never in new space. | 
| 3051 ASSERT(!Heap::InNewSpace(value)); | 3044 ASSERT(!Heap::InNewSpace(value)); | 
| 3052 Address entry = value->entry(); | 3045 Address entry = value->entry(); | 
| 3053 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry)); | 3046 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry)); | 
| 3047 IncrementalMarking::RecordWrite(this, value); | |
| 3054 } | 3048 } | 
| 3055 | 3049 | 
| 3056 | 3050 | 
| 3057 void JSFunction::ReplaceCode(Code* code) { | 3051 void JSFunction::ReplaceCode(Code* code) { | 
| 3058 bool was_optimized = IsOptimized(); | 3052 bool was_optimized = IsOptimized(); | 
| 3059 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION; | 3053 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION; | 
| 3060 | 3054 | 
| 3061 set_code(code); | 3055 set_code(code); | 
| 3062 | 3056 | 
| 3063 // Add/remove the function from the list of optimized functions for this | 3057 // Add/remove the function from the list of optimized functions for this | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 3083 | 3077 | 
| 3084 SharedFunctionInfo* JSFunction::unchecked_shared() { | 3078 SharedFunctionInfo* JSFunction::unchecked_shared() { | 
| 3085 return reinterpret_cast<SharedFunctionInfo*>( | 3079 return reinterpret_cast<SharedFunctionInfo*>( | 
| 3086 READ_FIELD(this, kSharedFunctionInfoOffset)); | 3080 READ_FIELD(this, kSharedFunctionInfoOffset)); | 
| 3087 } | 3081 } | 
| 3088 | 3082 | 
| 3089 | 3083 | 
| 3090 void JSFunction::set_context(Object* value) { | 3084 void JSFunction::set_context(Object* value) { | 
| 3091 ASSERT(value == Heap::undefined_value() || value->IsContext()); | 3085 ASSERT(value == Heap::undefined_value() || value->IsContext()); | 
| 3092 WRITE_FIELD(this, kContextOffset, value); | 3086 WRITE_FIELD(this, kContextOffset, value); | 
| 3093 WRITE_BARRIER(this, kContextOffset); | 3087 WRITE_BARRIER(this, kContextOffset, value); | 
| 3094 } | 3088 } | 
| 3095 | 3089 | 
| 3096 ACCESSORS(JSFunction, prototype_or_initial_map, Object, | 3090 ACCESSORS(JSFunction, prototype_or_initial_map, Object, | 
| 3097 kPrototypeOrInitialMapOffset) | 3091 kPrototypeOrInitialMapOffset) | 
| 3098 | 3092 | 
| 3099 | 3093 | 
| 3100 Map* JSFunction::initial_map() { | 3094 Map* JSFunction::initial_map() { | 
| 3101 return Map::cast(prototype_or_initial_map()); | 3095 return Map::cast(prototype_or_initial_map()); | 
| 3102 } | 3096 } | 
| 3103 | 3097 | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3157 Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) { | 3151 Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) { | 
| 3158 ASSERT(id < kJSBuiltinsCount); // id is unsigned. | 3152 ASSERT(id < kJSBuiltinsCount); // id is unsigned. | 
| 3159 return READ_FIELD(this, OffsetOfFunctionWithId(id)); | 3153 return READ_FIELD(this, OffsetOfFunctionWithId(id)); | 
| 3160 } | 3154 } | 
| 3161 | 3155 | 
| 3162 | 3156 | 
| 3163 void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id, | 3157 void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id, | 
| 3164 Object* value) { | 3158 Object* value) { | 
| 3165 ASSERT(id < kJSBuiltinsCount); // id is unsigned. | 3159 ASSERT(id < kJSBuiltinsCount); // id is unsigned. | 
| 3166 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value); | 3160 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value); | 
| 3167 WRITE_BARRIER(this, OffsetOfFunctionWithId(id)); | 3161 WRITE_BARRIER(this, OffsetOfFunctionWithId(id), value); | 
| 3168 } | 3162 } | 
| 3169 | 3163 | 
| 3170 | 3164 | 
| 3171 Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) { | 3165 Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) { | 
| 3172 ASSERT(id < kJSBuiltinsCount); // id is unsigned. | 3166 ASSERT(id < kJSBuiltinsCount); // id is unsigned. | 
| 3173 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id))); | 3167 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id))); | 
| 3174 } | 3168 } | 
| 3175 | 3169 | 
| 3176 | 3170 | 
| 3177 void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id, | 3171 void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id, | 
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3789 | 3783 | 
| 3790 | 3784 | 
| 3791 #undef CAST_ACCESSOR | 3785 #undef CAST_ACCESSOR | 
| 3792 #undef INT_ACCESSORS | 3786 #undef INT_ACCESSORS | 
| 3793 #undef SMI_ACCESSORS | 3787 #undef SMI_ACCESSORS | 
| 3794 #undef ACCESSORS | 3788 #undef ACCESSORS | 
| 3795 #undef FIELD_ADDR | 3789 #undef FIELD_ADDR | 
| 3796 #undef READ_FIELD | 3790 #undef READ_FIELD | 
| 3797 #undef WRITE_FIELD | 3791 #undef WRITE_FIELD | 
| 3798 #undef WRITE_BARRIER | 3792 #undef WRITE_BARRIER | 
| 3799 #undef CONDITIONAL_WRITE_BARRIER | |
| 3800 #undef READ_MEMADDR_FIELD | 3793 #undef READ_MEMADDR_FIELD | 
| 3801 #undef WRITE_MEMADDR_FIELD | 3794 #undef WRITE_MEMADDR_FIELD | 
| 3802 #undef READ_DOUBLE_FIELD | 3795 #undef READ_DOUBLE_FIELD | 
| 3803 #undef WRITE_DOUBLE_FIELD | 3796 #undef WRITE_DOUBLE_FIELD | 
| 3804 #undef READ_INT_FIELD | 3797 #undef READ_INT_FIELD | 
| 3805 #undef WRITE_INT_FIELD | 3798 #undef WRITE_INT_FIELD | 
| 3806 #undef READ_SHORT_FIELD | 3799 #undef READ_SHORT_FIELD | 
| 3807 #undef WRITE_SHORT_FIELD | 3800 #undef WRITE_SHORT_FIELD | 
| 3808 #undef READ_BYTE_FIELD | 3801 #undef READ_BYTE_FIELD | 
| 3809 #undef WRITE_BYTE_FIELD | 3802 #undef WRITE_BYTE_FIELD | 
| 3810 | 3803 | 
| 3811 | 3804 | 
| 3812 } } // namespace v8::internal | 3805 } } // namespace v8::internal | 
| 3813 | 3806 | 
| 3814 #endif // V8_OBJECTS_INL_H_ | 3807 #endif // V8_OBJECTS_INL_H_ | 
| OLD | NEW |