| 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE; | 107 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE; |
| 108 } | 108 } |
| 109 | 109 |
| 110 | 110 |
| 111 bool Object::IsString() { | 111 bool Object::IsString() { |
| 112 return Object::IsHeapObject() | 112 return Object::IsHeapObject() |
| 113 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE; | 113 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE; |
| 114 } | 114 } |
| 115 | 115 |
| 116 | 116 |
| 117 bool Object::IsSymbol() { |
| 118 if (!this->IsHeapObject()) return false; |
| 119 uint32_t type = HeapObject::cast(this)->map()->instance_type(); |
| 120 return (type & (kIsNotStringMask | kIsSymbolMask)) == |
| 121 (kStringTag | kSymbolTag); |
| 122 } |
| 123 |
| 124 |
| 125 bool Object::IsConsString() { |
| 126 if (!this->IsHeapObject()) return false; |
| 127 uint32_t type = HeapObject::cast(this)->map()->instance_type(); |
| 128 return (type & (kIsNotStringMask | kStringRepresentationMask)) == |
| 129 (kStringTag | kConsStringTag); |
| 130 } |
| 131 |
| 132 |
| 133 #ifdef DEBUG |
| 134 // These are for cast checks. If you need one of these in release |
| 135 // mode you should consider using a StringShape before moving it out |
| 136 // of the ifdef |
| 137 |
| 117 bool Object::IsSeqString() { | 138 bool Object::IsSeqString() { |
| 118 return IsString() | 139 if (!IsString()) return false; |
| 119 && (String::cast(this)->representation_tag() == kSeqStringTag); | 140 return StringShape(String::cast(this)).IsSequential(); |
| 120 } | 141 } |
| 121 | 142 |
| 122 | 143 |
| 123 bool Object::IsSeqAsciiString() { | 144 bool Object::IsSeqAsciiString() { |
| 124 return IsSeqString() | 145 if (!IsString()) return false; |
| 125 && String::cast(this)->IsAsciiRepresentation(); | 146 StringShape shape(String::cast(this)); |
| 126 } | 147 return shape.IsSequential() && shape.IsAsciiRepresentation(); |
| 127 | |
| 128 | |
| 129 bool String::IsSeqAsciiString() { | |
| 130 return (this->representation_tag() == kSeqStringTag) | |
| 131 && is_ascii_representation(); | |
| 132 } | 148 } |
| 133 | 149 |
| 134 | 150 |
| 135 bool Object::IsSeqTwoByteString() { | 151 bool Object::IsSeqTwoByteString() { |
| 136 return IsSeqString() | 152 if (!IsString()) return false; |
| 137 && !String::cast(this)->IsAsciiRepresentation(); | 153 StringShape shape(String::cast(this)); |
| 154 return shape.IsSequential() && shape.IsTwoByteRepresentation(); |
| 138 } | 155 } |
| 139 | 156 |
| 140 | 157 |
| 141 bool Object::IsAsciiStringRepresentation() { | 158 bool Object::IsExternalString() { |
| 142 return IsString() && (String::cast(this)->is_ascii_representation()); | 159 if (!IsString()) return false; |
| 160 return StringShape(String::cast(this)).IsExternal(); |
| 143 } | 161 } |
| 144 | 162 |
| 145 | 163 |
| 146 bool Object::IsTwoByteStringRepresentation() { | 164 bool Object::IsExternalAsciiString() { |
| 147 return IsString() && (!String::cast(this)->is_ascii_representation()); | 165 if (!IsString()) return false; |
| 166 StringShape shape(String::cast(this)); |
| 167 return shape.IsExternal() && shape.IsAsciiRepresentation(); |
| 148 } | 168 } |
| 149 | 169 |
| 150 | 170 |
| 151 bool Object::IsConsString() { | 171 bool Object::IsExternalTwoByteString() { |
| 152 return IsString() | 172 if (!IsString()) return false; |
| 153 && (String::cast(this)->representation_tag() == kConsStringTag); | 173 StringShape shape(String::cast(this)); |
| 174 return shape.IsExternal() && shape.IsTwoByteRepresentation(); |
| 154 } | 175 } |
| 155 | 176 |
| 156 | 177 |
| 157 bool Object::IsSlicedString() { | 178 bool Object::IsSlicedString() { |
| 158 return IsString() | 179 if (!IsString()) return false; |
| 159 && (String::cast(this)->representation_tag() == kSlicedStringTag); | 180 return StringShape(String::cast(this)).IsSliced(); |
| 160 } | 181 } |
| 161 | 182 |
| 162 | 183 |
| 163 bool Object::IsExternalString() { | 184 #endif // DEBUG |
| 164 return IsString() | 185 |
| 165 && (String::cast(this)->representation_tag() == kExternalStringTag); | 186 |
| 187 StringShape::StringShape(String* str) |
| 188 : type_(str->map()->instance_type()) { |
| 189 set_valid(); |
| 190 ASSERT((type_ & kIsNotStringMask) == kStringTag); |
| 166 } | 191 } |
| 167 | 192 |
| 168 | 193 |
| 169 bool Object::IsExternalAsciiString() { | 194 StringShape::StringShape(Map* map) |
| 170 return IsExternalString() && (String::cast(this)->is_ascii_representation()); | 195 : type_(map->instance_type()) { |
| 196 set_valid(); |
| 197 ASSERT((type_ & kIsNotStringMask) == kStringTag); |
| 171 } | 198 } |
| 172 | 199 |
| 173 | 200 |
| 174 bool Object::IsExternalTwoByteString() { | 201 StringShape::StringShape(InstanceType t) |
| 175 return IsExternalString() && (!String::cast(this)->is_ascii_representation()); | 202 : type_(static_cast<uint32_t>(t)) { |
| 203 set_valid(); |
| 204 ASSERT((type_ & kIsNotStringMask) == kStringTag); |
| 176 } | 205 } |
| 177 | 206 |
| 178 | 207 |
| 179 bool Object::IsShortString() { | 208 bool StringShape::IsSymbol() { |
| 180 return IsString() && (String::cast(this)->size_tag() == kShortStringTag); | 209 ASSERT(valid()); |
| 210 return (type_ & kIsSymbolMask) == kSymbolTag; |
| 181 } | 211 } |
| 182 | 212 |
| 183 | 213 |
| 184 bool Object::IsMediumString() { | 214 bool StringShape::IsAsciiRepresentation() { |
| 185 return IsString() && (String::cast(this)->size_tag() == kMediumStringTag); | 215 return (type_ & kStringEncodingMask) == kAsciiStringTag; |
| 186 } | 216 } |
| 187 | 217 |
| 188 | 218 |
| 189 bool Object::IsLongString() { | 219 bool StringShape::IsTwoByteRepresentation() { |
| 190 return IsString() && (String::cast(this)->size_tag() == kLongStringTag); | 220 return (type_ & kStringEncodingMask) == kTwoByteStringTag; |
| 191 } | 221 } |
| 192 | 222 |
| 193 | 223 |
| 194 bool Object::IsSymbol() { | 224 bool StringShape::IsCons() { |
| 195 return IsString() && (String::cast(this)->is_symbol()); | 225 return (type_ & kStringRepresentationMask) == kConsStringTag; |
| 226 } |
| 227 |
| 228 |
| 229 bool StringShape::IsSliced() { |
| 230 return (type_ & kStringRepresentationMask) == kSlicedStringTag; |
| 231 } |
| 232 |
| 233 |
| 234 bool StringShape::IsExternal() { |
| 235 return (type_ & kStringRepresentationMask) == kExternalStringTag; |
| 236 } |
| 237 |
| 238 |
| 239 bool StringShape::IsSequential() { |
| 240 return (type_ & kStringRepresentationMask) == kSeqStringTag; |
| 241 } |
| 242 |
| 243 |
| 244 StringRepresentationTag StringShape::representation_tag() { |
| 245 uint32_t tag = (type_ & kStringRepresentationMask); |
| 246 return static_cast<StringRepresentationTag>(tag); |
| 247 } |
| 248 |
| 249 |
| 250 uint32_t StringShape::full_representation_tag() { |
| 251 return (type_ & (kStringRepresentationMask | kStringEncodingMask)); |
| 252 } |
| 253 |
| 254 |
| 255 uint32_t StringShape::size_tag() { |
| 256 return (type_ & kStringSizeMask); |
| 257 } |
| 258 |
| 259 |
| 260 bool StringShape::IsSequentialAscii() { |
| 261 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag); |
| 262 } |
| 263 |
| 264 |
| 265 bool StringShape::IsSequentialTwoByte() { |
| 266 return (type_ & (kStringRepresentationMask | kStringEncodingMask)) == |
| 267 (kSeqStringTag | kTwoByteStringTag); |
| 268 } |
| 269 |
| 270 |
| 271 bool StringShape::IsExternalAscii() { |
| 272 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag); |
| 273 } |
| 274 |
| 275 |
| 276 bool StringShape::IsExternalTwoByte() { |
| 277 return (type_ & (kStringRepresentationMask | kStringEncodingMask)) == |
| 278 (kExternalStringTag | kTwoByteStringTag); |
| 196 } | 279 } |
| 197 | 280 |
| 198 | 281 |
| 199 bool Object::IsNumber() { | 282 bool Object::IsNumber() { |
| 200 return IsSmi() || IsHeapNumber(); | 283 return IsSmi() || IsHeapNumber(); |
| 201 } | 284 } |
| 202 | 285 |
| 203 | 286 |
| 204 bool Object::IsByteArray() { | 287 bool Object::IsByteArray() { |
| 205 return Object::IsHeapObject() | 288 return Object::IsHeapObject() |
| (...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1121 void DescriptorArray::fast_swap(FixedArray* array, int first, int second) { | 1204 void DescriptorArray::fast_swap(FixedArray* array, int first, int second) { |
| 1122 Object* tmp = array->get(first); | 1205 Object* tmp = array->get(first); |
| 1123 fast_set(array, first, array->get(second)); | 1206 fast_set(array, first, array->get(second)); |
| 1124 fast_set(array, second, tmp); | 1207 fast_set(array, second, tmp); |
| 1125 } | 1208 } |
| 1126 | 1209 |
| 1127 | 1210 |
| 1128 int DescriptorArray::Search(String* name) { | 1211 int DescriptorArray::Search(String* name) { |
| 1129 SLOW_ASSERT(IsSortedNoDuplicates()); | 1212 SLOW_ASSERT(IsSortedNoDuplicates()); |
| 1130 | 1213 |
| 1214 StringShape shape(name); |
| 1215 |
| 1131 // Check for empty descriptor array. | 1216 // Check for empty descriptor array. |
| 1132 int nof = number_of_descriptors(); | 1217 int nof = number_of_descriptors(); |
| 1133 if (nof == 0) return kNotFound; | 1218 if (nof == 0) return kNotFound; |
| 1134 | 1219 |
| 1135 // Fast case: do linear search for small arrays. | 1220 // Fast case: do linear search for small arrays. |
| 1136 const int kMaxElementsForLinearSearch = 8; | 1221 const int kMaxElementsForLinearSearch = 8; |
| 1137 if (name->IsSymbol() && nof < kMaxElementsForLinearSearch) { | 1222 if (shape.IsSymbol() && nof < kMaxElementsForLinearSearch) { |
| 1138 return LinearSearch(name, nof); | 1223 return LinearSearch(name, nof); |
| 1139 } | 1224 } |
| 1140 | 1225 |
| 1141 // Slow case: perform binary search. | 1226 // Slow case: perform binary search. |
| 1142 return BinarySearch(name, 0, nof - 1); | 1227 return BinarySearch(name, 0, nof - 1); |
| 1143 } | 1228 } |
| 1144 | 1229 |
| 1145 | 1230 |
| 1146 | 1231 |
| 1147 String* DescriptorArray::GetKey(int descriptor_number) { | 1232 String* DescriptorArray::GetKey(int descriptor_number) { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 ASSERT(obj->IsHashTable()); | 1346 ASSERT(obj->IsHashTable()); |
| 1262 return reinterpret_cast<HashTable*>(obj); | 1347 return reinterpret_cast<HashTable*>(obj); |
| 1263 } | 1348 } |
| 1264 | 1349 |
| 1265 | 1350 |
| 1266 INT_ACCESSORS(Array, length, kLengthOffset) | 1351 INT_ACCESSORS(Array, length, kLengthOffset) |
| 1267 | 1352 |
| 1268 | 1353 |
| 1269 bool String::Equals(String* other) { | 1354 bool String::Equals(String* other) { |
| 1270 if (other == this) return true; | 1355 if (other == this) return true; |
| 1271 if (IsSymbol() && other->IsSymbol()) return false; | 1356 StringShape this_shape(this); |
| 1272 return SlowEquals(other); | 1357 StringShape other_shape(other); |
| 1358 if (this_shape.IsSymbol() && other_shape.IsSymbol()) return false; |
| 1359 return SlowEquals(this_shape, other, other_shape); |
| 1273 } | 1360 } |
| 1274 | 1361 |
| 1275 | 1362 |
| 1276 int String::length() { | 1363 int String::length(StringShape shape) { |
| 1364 ASSERT(shape.type() == StringShape(this).type()); |
| 1277 uint32_t len = READ_INT_FIELD(this, kLengthOffset); | 1365 uint32_t len = READ_INT_FIELD(this, kLengthOffset); |
| 1278 | 1366 |
| 1279 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); | 1367 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); |
| 1280 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); | 1368 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); |
| 1281 ASSERT(kLongStringTag == 0); | 1369 ASSERT(kLongStringTag == 0); |
| 1282 | 1370 |
| 1283 return len >> (size_tag() + kLongLengthShift); | 1371 return len >> (shape.size_tag() + kLongLengthShift); |
| 1372 } |
| 1373 |
| 1374 |
| 1375 int String::length() { |
| 1376 return length(StringShape(this)); |
| 1284 } | 1377 } |
| 1285 | 1378 |
| 1286 | 1379 |
| 1287 void String::set_length(int value) { | 1380 void String::set_length(int value) { |
| 1288 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); | 1381 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); |
| 1289 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); | 1382 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); |
| 1290 ASSERT(kLongStringTag == 0); | 1383 ASSERT(kLongStringTag == 0); |
| 1291 | 1384 |
| 1385 StringShape shape(this); |
| 1292 WRITE_INT_FIELD(this, | 1386 WRITE_INT_FIELD(this, |
| 1293 kLengthOffset, | 1387 kLengthOffset, |
| 1294 value << (size_tag() + kLongLengthShift)); | 1388 value << (shape.size_tag() + kLongLengthShift)); |
| 1295 } | 1389 } |
| 1296 | 1390 |
| 1297 | 1391 |
| 1298 uint32_t String::length_field() { | 1392 uint32_t String::length_field() { |
| 1299 return READ_UINT32_FIELD(this, kLengthOffset); | 1393 return READ_UINT32_FIELD(this, kLengthOffset); |
| 1300 } | 1394 } |
| 1301 | 1395 |
| 1302 | 1396 |
| 1303 void String::set_length_field(uint32_t value) { | 1397 void String::set_length_field(uint32_t value) { |
| 1304 WRITE_UINT32_FIELD(this, kLengthOffset, value); | 1398 WRITE_UINT32_FIELD(this, kLengthOffset, value); |
| 1305 } | 1399 } |
| 1306 | 1400 |
| 1307 | 1401 |
| 1308 void String::TryFlatten() { | 1402 void String::TryFlatten(StringShape shape) { |
| 1403 ASSERT(shape.type() == StringShape(this).type()); |
| 1309 // We don't need to flatten strings that are already flat. Since this code | 1404 // We don't need to flatten strings that are already flat. Since this code |
| 1310 // is inlined, it can be helpful in the flat case to not call out to Flatten. | 1405 // is inlined, it can be helpful in the flat case to not call out to Flatten. |
| 1311 StringRepresentationTag str_type = representation_tag(); | 1406 if (!IsFlat(shape)) { |
| 1312 if (str_type != kSeqStringTag && str_type != kExternalStringTag) { | 1407 Flatten(shape); |
| 1313 Flatten(); | |
| 1314 } | 1408 } |
| 1315 } | 1409 } |
| 1316 | 1410 |
| 1317 | 1411 |
| 1318 uint16_t String::Get(int index) { | 1412 uint16_t String::Get(StringShape shape, int index) { |
| 1319 ASSERT(index >= 0 && index < length()); | 1413 ASSERT(shape.type() == StringShape(this).type()); |
| 1320 switch (representation_tag()) { | 1414 ASSERT(index >= 0 && index < length(shape)); |
| 1321 case kSeqStringTag: | 1415 switch (shape.full_representation_tag()) { |
| 1322 return is_ascii_representation() | 1416 case kSeqStringTag | kAsciiStringTag: |
| 1323 ? SeqAsciiString::cast(this)->SeqAsciiStringGet(index) | 1417 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index); |
| 1324 : SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); | 1418 case kSeqStringTag | kTwoByteStringTag: |
| 1325 case kConsStringTag: | 1419 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); |
| 1420 case kConsStringTag | kAsciiStringTag: |
| 1421 case kConsStringTag | kTwoByteStringTag: |
| 1326 return ConsString::cast(this)->ConsStringGet(index); | 1422 return ConsString::cast(this)->ConsStringGet(index); |
| 1327 case kSlicedStringTag: | 1423 case kSlicedStringTag | kAsciiStringTag: |
| 1424 case kSlicedStringTag | kTwoByteStringTag: |
| 1328 return SlicedString::cast(this)->SlicedStringGet(index); | 1425 return SlicedString::cast(this)->SlicedStringGet(index); |
| 1329 case kExternalStringTag: | 1426 case kExternalStringTag | kAsciiStringTag: |
| 1330 return is_ascii_representation() | 1427 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index); |
| 1331 ? ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index) | 1428 case kExternalStringTag | kTwoByteStringTag: |
| 1332 : ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); | 1429 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); |
| 1333 default: | 1430 default: |
| 1334 break; | 1431 break; |
| 1335 } | 1432 } |
| 1336 | 1433 |
| 1337 UNREACHABLE(); | 1434 UNREACHABLE(); |
| 1338 return 0; | 1435 return 0; |
| 1339 } | 1436 } |
| 1340 | 1437 |
| 1341 | 1438 |
| 1342 void String::Set(int index, uint16_t value) { | 1439 void String::Set(StringShape shape, int index, uint16_t value) { |
| 1343 ASSERT(index >= 0 && index < length()); | 1440 ASSERT(shape.type() == StringShape(this).type()); |
| 1344 ASSERT(IsSeqString()); | 1441 ASSERT(shape.type() == StringShape(this).type()); |
| 1442 ASSERT(index >= 0 && index < length(shape)); |
| 1443 ASSERT(shape.IsSequential()); |
| 1345 | 1444 |
| 1346 return is_ascii_representation() | 1445 return shape.IsAsciiRepresentation() |
| 1347 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value) | 1446 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value) |
| 1348 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value); | 1447 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value); |
| 1349 } | 1448 } |
| 1350 | 1449 |
| 1351 | 1450 |
| 1352 bool String::IsAsciiRepresentation() { | 1451 bool String::IsFlat(StringShape shape) { |
| 1353 return is_ascii_representation(); | 1452 ASSERT(shape.type() == StringShape(this).type()); |
| 1354 } | 1453 switch (shape.representation_tag()) { |
| 1355 | 1454 case kConsStringTag: { |
| 1356 | 1455 String* second = ConsString::cast(this)->second(); |
| 1357 bool String::StringIsConsString() { | |
| 1358 return representation_tag() == kConsStringTag; | |
| 1359 } | |
| 1360 | |
| 1361 | |
| 1362 bool String::StringIsSlicedString() { | |
| 1363 return representation_tag() == kSlicedStringTag; | |
| 1364 } | |
| 1365 | |
| 1366 | |
| 1367 uint32_t String::size_tag() { | |
| 1368 return map_size_tag(map()); | |
| 1369 } | |
| 1370 | |
| 1371 | |
| 1372 uint32_t String::map_size_tag(Map* map) { | |
| 1373 return map->instance_type() & kStringSizeMask; | |
| 1374 } | |
| 1375 | |
| 1376 | |
| 1377 bool String::is_symbol() { | |
| 1378 return is_symbol_map(map()); | |
| 1379 } | |
| 1380 | |
| 1381 | |
| 1382 bool String::is_symbol_map(Map* map) { | |
| 1383 return (map->instance_type() & kIsSymbolMask) != 0; | |
| 1384 } | |
| 1385 | |
| 1386 | |
| 1387 bool String::is_ascii_representation() { | |
| 1388 return is_ascii_representation_map(map()); | |
| 1389 } | |
| 1390 | |
| 1391 | |
| 1392 bool String::is_ascii_representation_map(Map* map) { | |
| 1393 return (map->instance_type() & kStringEncodingMask) != 0; | |
| 1394 } | |
| 1395 | |
| 1396 | |
| 1397 int String::full_representation_tag() { | |
| 1398 return map()->instance_type() & | |
| 1399 (kStringRepresentationMask | kStringEncodingMask); | |
| 1400 } | |
| 1401 | |
| 1402 | |
| 1403 StringRepresentationTag String::representation_tag() { | |
| 1404 return map_representation_tag(map()); | |
| 1405 } | |
| 1406 | |
| 1407 | |
| 1408 StringRepresentationTag String::map_representation_tag(Map* map) { | |
| 1409 uint32_t tag = map->instance_type() & kStringRepresentationMask; | |
| 1410 return static_cast<StringRepresentationTag>(tag); | |
| 1411 } | |
| 1412 | |
| 1413 | |
| 1414 bool String::IsFlat() { | |
| 1415 switch (this->representation_tag()) { | |
| 1416 case kConsStringTag: | |
| 1417 // Only flattened strings have second part empty. | 1456 // Only flattened strings have second part empty. |
| 1418 return String::cast(ConsString::cast(this)->second())->length() == 0; | 1457 return second->length() == 0; |
| 1458 } |
| 1419 case kSlicedStringTag: { | 1459 case kSlicedStringTag: { |
| 1420 String* slice = String::cast(SlicedString::cast(this)->buffer()); | 1460 StringShape slice_shape = StringShape(SlicedString::cast(this)->buffer()); |
| 1421 StringRepresentationTag tag = slice->representation_tag(); | 1461 StringRepresentationTag tag = slice_shape.representation_tag(); |
| 1422 return tag == kSeqStringTag || tag == kExternalStringTag; | 1462 return tag == kSeqStringTag || tag == kExternalStringTag; |
| 1423 } | 1463 } |
| 1424 default: | 1464 default: |
| 1425 return true; | 1465 return true; |
| 1426 } | 1466 } |
| 1427 } | 1467 } |
| 1428 | 1468 |
| 1429 | 1469 |
| 1430 uint16_t SeqAsciiString::SeqAsciiStringGet(int index) { | 1470 uint16_t SeqAsciiString::SeqAsciiStringGet(int index) { |
| 1431 ASSERT(index >= 0 && index < length()); | 1471 ASSERT(index >= 0 && index < length()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1465 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize); | 1505 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize); |
| 1466 } | 1506 } |
| 1467 | 1507 |
| 1468 | 1508 |
| 1469 void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) { | 1509 void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) { |
| 1470 ASSERT(index >= 0 && index < length()); | 1510 ASSERT(index >= 0 && index < length()); |
| 1471 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value); | 1511 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value); |
| 1472 } | 1512 } |
| 1473 | 1513 |
| 1474 | 1514 |
| 1475 int SeqTwoByteString::SeqTwoByteStringSize(Map* map) { | 1515 int SeqTwoByteString::SeqTwoByteStringSize(StringShape shape) { |
| 1476 uint32_t length = READ_INT_FIELD(this, kLengthOffset); | 1516 uint32_t length = READ_INT_FIELD(this, kLengthOffset); |
| 1477 | 1517 |
| 1478 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); | 1518 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); |
| 1479 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); | 1519 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); |
| 1480 ASSERT(kLongStringTag == 0); | 1520 ASSERT(kLongStringTag == 0); |
| 1481 | 1521 |
| 1482 // Use the map (and not 'this') to compute the size tag, since | 1522 // Use the map (and not 'this') to compute the size tag, since |
| 1483 // TwoByteStringSize is called during GC when maps are encoded. | 1523 // TwoByteStringSize is called during GC when maps are encoded. |
| 1484 length >>= map_size_tag(map) + kLongLengthShift; | 1524 length >>= shape.size_tag() + kLongLengthShift; |
| 1485 | 1525 |
| 1486 return SizeFor(length); | 1526 return SizeFor(length); |
| 1487 } | 1527 } |
| 1488 | 1528 |
| 1489 | 1529 |
| 1490 int SeqAsciiString::SeqAsciiStringSize(Map* map) { | 1530 int SeqAsciiString::SeqAsciiStringSize(StringShape shape) { |
| 1491 uint32_t length = READ_INT_FIELD(this, kLengthOffset); | 1531 uint32_t length = READ_INT_FIELD(this, kLengthOffset); |
| 1492 | 1532 |
| 1493 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); | 1533 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); |
| 1494 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); | 1534 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); |
| 1495 ASSERT(kLongStringTag == 0); | 1535 ASSERT(kLongStringTag == 0); |
| 1496 | 1536 |
| 1497 // Use the map (and not 'this') to compute the size tag, since | 1537 // Use the map (and not 'this') to compute the size tag, since |
| 1498 // AsciiStringSize is called during GC when maps are encoded. | 1538 // AsciiStringSize is called during GC when maps are encoded. |
| 1499 length >>= map_size_tag(map) + kLongLengthShift; | 1539 length >>= shape.size_tag() + kLongLengthShift; |
| 1500 | 1540 |
| 1501 return SizeFor(length); | 1541 return SizeFor(length); |
| 1502 } | 1542 } |
| 1503 | 1543 |
| 1504 | 1544 |
| 1505 Object* ConsString::first() { | 1545 String* ConsString::first() { |
| 1546 return String::cast(READ_FIELD(this, kFirstOffset)); |
| 1547 } |
| 1548 |
| 1549 |
| 1550 Object* ConsString::unchecked_first() { |
| 1506 return READ_FIELD(this, kFirstOffset); | 1551 return READ_FIELD(this, kFirstOffset); |
| 1507 } | 1552 } |
| 1508 | 1553 |
| 1509 | 1554 |
| 1510 void ConsString::set_first(Object* value, WriteBarrierMode mode) { | 1555 void ConsString::set_first(String* value, WriteBarrierMode mode) { |
| 1511 WRITE_FIELD(this, kFirstOffset, value); | 1556 WRITE_FIELD(this, kFirstOffset, value); |
| 1512 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode); | 1557 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode); |
| 1513 } | 1558 } |
| 1514 | 1559 |
| 1515 | 1560 |
| 1516 Object* ConsString::second() { | 1561 String* ConsString::second() { |
| 1562 return String::cast(READ_FIELD(this, kSecondOffset)); |
| 1563 } |
| 1564 |
| 1565 |
| 1566 Object* ConsString::unchecked_second() { |
| 1517 return READ_FIELD(this, kSecondOffset); | 1567 return READ_FIELD(this, kSecondOffset); |
| 1518 } | 1568 } |
| 1519 | 1569 |
| 1520 | 1570 |
| 1521 void ConsString::set_second(Object* value, WriteBarrierMode mode) { | 1571 void ConsString::set_second(String* value, WriteBarrierMode mode) { |
| 1522 WRITE_FIELD(this, kSecondOffset, value); | 1572 WRITE_FIELD(this, kSecondOffset, value); |
| 1523 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode); | 1573 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode); |
| 1524 } | 1574 } |
| 1525 | 1575 |
| 1526 | 1576 |
| 1527 Object* SlicedString::buffer() { | 1577 String* SlicedString::buffer() { |
| 1528 return READ_FIELD(this, kBufferOffset); | 1578 return String::cast(READ_FIELD(this, kBufferOffset)); |
| 1529 } | 1579 } |
| 1530 | 1580 |
| 1531 | 1581 |
| 1532 void SlicedString::set_buffer(Object* buffer) { | 1582 void SlicedString::set_buffer(String* buffer) { |
| 1533 WRITE_FIELD(this, kBufferOffset, buffer); | 1583 WRITE_FIELD(this, kBufferOffset, buffer); |
| 1534 WRITE_BARRIER(this, kBufferOffset); | 1584 WRITE_BARRIER(this, kBufferOffset); |
| 1535 } | 1585 } |
| 1536 | 1586 |
| 1537 | 1587 |
| 1538 int SlicedString::start() { | 1588 int SlicedString::start() { |
| 1539 return READ_INT_FIELD(this, kStartOffset); | 1589 return READ_INT_FIELD(this, kStartOffset); |
| 1540 } | 1590 } |
| 1541 | 1591 |
| 1542 | 1592 |
| (...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2384 #undef WRITE_INT_FIELD | 2434 #undef WRITE_INT_FIELD |
| 2385 #undef READ_SHORT_FIELD | 2435 #undef READ_SHORT_FIELD |
| 2386 #undef WRITE_SHORT_FIELD | 2436 #undef WRITE_SHORT_FIELD |
| 2387 #undef READ_BYTE_FIELD | 2437 #undef READ_BYTE_FIELD |
| 2388 #undef WRITE_BYTE_FIELD | 2438 #undef WRITE_BYTE_FIELD |
| 2389 | 2439 |
| 2390 | 2440 |
| 2391 } } // namespace v8::internal | 2441 } } // namespace v8::internal |
| 2392 | 2442 |
| 2393 #endif // V8_OBJECTS_INL_H_ | 2443 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |