Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: src/utils.h

Issue 302563004: Move OS::MemCopy and OS::MemMove out of platform to utils (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/unicode-inl.h ('k') | src/utils.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_UTILS_H_ 5 #ifndef V8_UTILS_H_
6 #define V8_UTILS_H_ 6 #define V8_UTILS_H_
7 7
8 #include <limits.h> 8 #include <limits.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <string.h> 10 #include <string.h>
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 315
316 316
317 inline uint32_t ComputePointerHash(void* ptr) { 317 inline uint32_t ComputePointerHash(void* ptr) {
318 return ComputeIntegerHash( 318 return ComputeIntegerHash(
319 static_cast<uint32_t>(reinterpret_cast<intptr_t>(ptr)), 319 static_cast<uint32_t>(reinterpret_cast<intptr_t>(ptr)),
320 v8::internal::kZeroHashSeed); 320 v8::internal::kZeroHashSeed);
321 } 321 }
322 322
323 323
324 // ---------------------------------------------------------------------------- 324 // ----------------------------------------------------------------------------
325 // Generated memcpy/memmove
326
327 // Initializes the codegen support that depends on CPU features. This is
328 // called after CPU initialization.
329 void init_memcopy_functions();
330
331 #if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X87)
332 // Limit below which the extra overhead of the MemCopy function is likely
333 // to outweigh the benefits of faster copying.
334 const int kMinComplexMemCopy = 64;
335
336 // Copy memory area. No restrictions.
337 void MemMove(void* dest, const void* src, size_t size);
338 typedef void (*MemMoveFunction)(void* dest, const void* src, size_t size);
339
340 // Keep the distinction of "move" vs. "copy" for the benefit of other
341 // architectures.
342 V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
343 MemMove(dest, src, size);
344 }
345 #elif defined(V8_HOST_ARCH_ARM)
346 typedef void (*MemCopyUint8Function)(uint8_t* dest, const uint8_t* src,
347 size_t size);
348 MemCopyUint8Function memcopy_uint8_function;
349 void MemCopyUint8Wrapper(uint8_t* dest, const uint8_t* src, size_t chars) {
350 memcpy(dest, src, chars);
351 }
352 // For values < 16, the assembler function is slower than the inlined C code.
353 const int kMinComplexMemCopy = 16;
354 V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
355 (*memcopy_uint8_function)(reinterpret_cast<uint8_t*>(dest),
356 reinterpret_cast<const uint8_t*>(src), size);
357 }
358 V8_INLINE void MemMove(void* dest, const void* src, size_t size) {
359 memmove(dest, src, size);
360 }
361
362 typedef void (*MemCopyUint16Uint8Function)(uint16_t* dest, const uint8_t* src,
363 size_t size);
364 MemCopyUint16Uint8Function memcopy_uint16_uint8_function;
365 void MemCopyUint16Uint8Wrapper(uint16_t* dest, const uint8_t* src,
366 size_t chars);
367 // For values < 12, the assembler function is slower than the inlined C code.
368 const int kMinComplexConvertMemCopy = 12;
369 V8_INLINE void MemCopyUint16Uint8(uint16_t* dest, const uint8_t* src,
370 size_t size) {
371 (*memcopy_uint16_uint8_function)(dest, src, size);
372 }
373 #elif defined(V8_HOST_ARCH_MIPS)
374 typedef void (*MemCopyUint8Function)(uint8_t* dest, const uint8_t* src,
375 size_t size);
376 MemCopyUint8Function memcopy_uint8_function;
377 V8_INLINE void MemCopyUint8Wrapper(uint8_t* dest, const uint8_t* src,
378 size_t chars) {
379 memcpy(dest, src, chars);
380 }
381 // For values < 16, the assembler function is slower than the inlined C code.
382 const int kMinComplexMemCopy = 16;
383 V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
384 (*memcopy_uint8_function)(reinterpret_cast<uint8_t*>(dest),
385 reinterpret_cast<const uint8_t*>(src), size);
386 }
387 V8_INLINE void MemMove(void* dest, const void* src, size_t size) {
388 memmove(dest, src, size);
389 }
390 #else
391 // Copy memory area to disjoint memory area.
392 V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
393 memcpy(dest, src, size);
394 }
395 V8_INLINE void MemMove(void* dest, const void* src, size_t size) {
396 memmove(dest, src, size);
397 }
398 const int kMinComplexMemCopy = 16 * kPointerSize;
399 #endif // V8_TARGET_ARCH_IA32
400
401
402 // ----------------------------------------------------------------------------
325 // Miscellaneous 403 // Miscellaneous
326 404
327 // A static resource holds a static instance that can be reserved in 405 // A static resource holds a static instance that can be reserved in
328 // a local scope using an instance of Access. Attempts to re-reserve 406 // a local scope using an instance of Access. Attempts to re-reserve
329 // the instance will cause an error. 407 // the instance will cause an error.
330 template <typename T> 408 template <typename T>
331 class StaticResource { 409 class StaticResource {
332 public: 410 public:
333 StaticResource() : is_reserved_(false) {} 411 StaticResource() : is_reserved_(false) {}
334 412
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 473
396 explicit EmbeddedVector(T initial_value) : Vector<T>(buffer_, kSize) { 474 explicit EmbeddedVector(T initial_value) : Vector<T>(buffer_, kSize) {
397 for (int i = 0; i < kSize; ++i) { 475 for (int i = 0; i < kSize; ++i) {
398 buffer_[i] = initial_value; 476 buffer_[i] = initial_value;
399 } 477 }
400 } 478 }
401 479
402 // When copying, make underlying Vector to reference our buffer. 480 // When copying, make underlying Vector to reference our buffer.
403 EmbeddedVector(const EmbeddedVector& rhs) 481 EmbeddedVector(const EmbeddedVector& rhs)
404 : Vector<T>(rhs) { 482 : Vector<T>(rhs) {
405 OS::MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize); 483 MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
406 set_start(buffer_); 484 set_start(buffer_);
407 } 485 }
408 486
409 EmbeddedVector& operator=(const EmbeddedVector& rhs) { 487 EmbeddedVector& operator=(const EmbeddedVector& rhs) {
410 if (this == &rhs) return *this; 488 if (this == &rhs) return *this;
411 Vector<T>::operator=(rhs); 489 Vector<T>::operator=(rhs);
412 OS::MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize); 490 MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
413 this->set_start(buffer_); 491 this->set_start(buffer_);
414 return *this; 492 return *this;
415 } 493 }
416 494
417 private: 495 private:
418 T buffer_[kSize]; 496 T buffer_[kSize];
419 }; 497 };
420 498
421 499
422 /* 500 /*
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 template <typename T> 1211 template <typename T>
1134 inline void CopyWords(T* dst, const T* src, size_t num_words) { 1212 inline void CopyWords(T* dst, const T* src, size_t num_words) {
1135 STATIC_ASSERT(sizeof(T) == kPointerSize); 1213 STATIC_ASSERT(sizeof(T) == kPointerSize);
1136 // TODO(mvstanton): disabled because mac builds are bogus failing on this 1214 // TODO(mvstanton): disabled because mac builds are bogus failing on this
1137 // assert. They are doing a signed comparison. Investigate in 1215 // assert. They are doing a signed comparison. Investigate in
1138 // the morning. 1216 // the morning.
1139 // ASSERT(Min(dst, const_cast<T*>(src)) + num_words <= 1217 // ASSERT(Min(dst, const_cast<T*>(src)) + num_words <=
1140 // Max(dst, const_cast<T*>(src))); 1218 // Max(dst, const_cast<T*>(src)));
1141 ASSERT(num_words > 0); 1219 ASSERT(num_words > 0);
1142 1220
1143 // Use block copying OS::MemCopy if the segment we're copying is 1221 // Use block copying MemCopy if the segment we're copying is
1144 // enough to justify the extra call/setup overhead. 1222 // enough to justify the extra call/setup overhead.
1145 static const size_t kBlockCopyLimit = 16; 1223 static const size_t kBlockCopyLimit = 16;
1146 1224
1147 if (num_words < kBlockCopyLimit) { 1225 if (num_words < kBlockCopyLimit) {
1148 do { 1226 do {
1149 num_words--; 1227 num_words--;
1150 *dst++ = *src++; 1228 *dst++ = *src++;
1151 } while (num_words > 0); 1229 } while (num_words > 0);
1152 } else { 1230 } else {
1153 OS::MemCopy(dst, src, num_words * kPointerSize); 1231 MemCopy(dst, src, num_words * kPointerSize);
1154 } 1232 }
1155 } 1233 }
1156 1234
1157 1235
1158 // Copies words from |src| to |dst|. No restrictions. 1236 // Copies words from |src| to |dst|. No restrictions.
1159 template <typename T> 1237 template <typename T>
1160 inline void MoveWords(T* dst, const T* src, size_t num_words) { 1238 inline void MoveWords(T* dst, const T* src, size_t num_words) {
1161 STATIC_ASSERT(sizeof(T) == kPointerSize); 1239 STATIC_ASSERT(sizeof(T) == kPointerSize);
1162 ASSERT(num_words > 0); 1240 ASSERT(num_words > 0);
1163 1241
1164 // Use block copying OS::MemCopy if the segment we're copying is 1242 // Use block copying MemCopy if the segment we're copying is
1165 // enough to justify the extra call/setup overhead. 1243 // enough to justify the extra call/setup overhead.
1166 static const size_t kBlockCopyLimit = 16; 1244 static const size_t kBlockCopyLimit = 16;
1167 1245
1168 if (num_words < kBlockCopyLimit && 1246 if (num_words < kBlockCopyLimit &&
1169 ((dst < src) || (dst >= (src + num_words * kPointerSize)))) { 1247 ((dst < src) || (dst >= (src + num_words * kPointerSize)))) {
1170 T* end = dst + num_words; 1248 T* end = dst + num_words;
1171 do { 1249 do {
1172 num_words--; 1250 num_words--;
1173 *dst++ = *src++; 1251 *dst++ = *src++;
1174 } while (num_words > 0); 1252 } while (num_words > 0);
1175 } else { 1253 } else {
1176 OS::MemMove(dst, src, num_words * kPointerSize); 1254 MemMove(dst, src, num_words * kPointerSize);
1177 } 1255 }
1178 } 1256 }
1179 1257
1180 1258
1181 // Copies data from |src| to |dst|. The data spans must not overlap. 1259 // Copies data from |src| to |dst|. The data spans must not overlap.
1182 template <typename T> 1260 template <typename T>
1183 inline void CopyBytes(T* dst, const T* src, size_t num_bytes) { 1261 inline void CopyBytes(T* dst, const T* src, size_t num_bytes) {
1184 STATIC_ASSERT(sizeof(T) == 1); 1262 STATIC_ASSERT(sizeof(T) == 1);
1185 ASSERT(Min(dst, const_cast<T*>(src)) + num_bytes <= 1263 ASSERT(Min(dst, const_cast<T*>(src)) + num_bytes <=
1186 Max(dst, const_cast<T*>(src))); 1264 Max(dst, const_cast<T*>(src)));
1187 if (num_bytes == 0) return; 1265 if (num_bytes == 0) return;
1188 1266
1189 // Use block copying OS::MemCopy if the segment we're copying is 1267 // Use block copying MemCopy if the segment we're copying is
1190 // enough to justify the extra call/setup overhead. 1268 // enough to justify the extra call/setup overhead.
1191 static const int kBlockCopyLimit = OS::kMinComplexMemCopy; 1269 static const int kBlockCopyLimit = kMinComplexMemCopy;
1192 1270
1193 if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) { 1271 if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) {
1194 do { 1272 do {
1195 num_bytes--; 1273 num_bytes--;
1196 *dst++ = *src++; 1274 *dst++ = *src++;
1197 } while (num_bytes > 0); 1275 } while (num_bytes > 0);
1198 } else { 1276 } else {
1199 OS::MemCopy(dst, src, num_bytes); 1277 MemCopy(dst, src, num_bytes);
1200 } 1278 }
1201 } 1279 }
1202 1280
1203 1281
1204 template <typename T, typename U> 1282 template <typename T, typename U>
1205 inline void MemsetPointer(T** dest, U* value, int counter) { 1283 inline void MemsetPointer(T** dest, U* value, int counter) {
1206 #ifdef DEBUG 1284 #ifdef DEBUG
1207 T* a = NULL; 1285 T* a = NULL;
1208 U* b = NULL; 1286 U* b = NULL;
1209 a = b; // Fake assignment to check assignability. 1287 a = b; // Fake assignment to check assignability.
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 chars); 1390 chars);
1313 } 1391 }
1314 } 1392 }
1315 } 1393 }
1316 1394
1317 template <typename sourcechar, typename sinkchar> 1395 template <typename sourcechar, typename sinkchar>
1318 void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) { 1396 void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
1319 sinkchar* limit = dest + chars; 1397 sinkchar* limit = dest + chars;
1320 #ifdef V8_HOST_CAN_READ_UNALIGNED 1398 #ifdef V8_HOST_CAN_READ_UNALIGNED
1321 if (sizeof(*dest) == sizeof(*src)) { 1399 if (sizeof(*dest) == sizeof(*src)) {
1322 if (chars >= static_cast<int>(OS::kMinComplexMemCopy / sizeof(*dest))) { 1400 if (chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest))) {
1323 OS::MemCopy(dest, src, chars * sizeof(*dest)); 1401 MemCopy(dest, src, chars * sizeof(*dest));
1324 return; 1402 return;
1325 } 1403 }
1326 // Number of characters in a uintptr_t. 1404 // Number of characters in a uintptr_t.
1327 static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest); // NOLINT 1405 static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest); // NOLINT
1328 ASSERT(dest + kStepSize > dest); // Check for overflow. 1406 ASSERT(dest + kStepSize > dest); // Check for overflow.
1329 while (dest + kStepSize <= limit) { 1407 while (dest + kStepSize <= limit) {
1330 *reinterpret_cast<uintptr_t*>(dest) = 1408 *reinterpret_cast<uintptr_t*>(dest) =
1331 *reinterpret_cast<const uintptr_t*>(src); 1409 *reinterpret_cast<const uintptr_t*>(src);
1332 dest += kStepSize; 1410 dest += kStepSize;
1333 src += kStepSize; 1411 src += kStepSize;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 case 13: 1462 case 13:
1385 memcpy(dest, src, 13); 1463 memcpy(dest, src, 13);
1386 break; 1464 break;
1387 case 14: 1465 case 14:
1388 memcpy(dest, src, 14); 1466 memcpy(dest, src, 14);
1389 break; 1467 break;
1390 case 15: 1468 case 15:
1391 memcpy(dest, src, 15); 1469 memcpy(dest, src, 15);
1392 break; 1470 break;
1393 default: 1471 default:
1394 OS::MemCopy(dest, src, chars); 1472 MemCopy(dest, src, chars);
1395 break; 1473 break;
1396 } 1474 }
1397 } 1475 }
1398 1476
1399 1477
1400 void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars) { 1478 void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars) {
1401 if (chars >= OS::kMinComplexConvertMemCopy) { 1479 if (chars >= kMinComplexConvertMemCopy) {
1402 OS::MemCopyUint16Uint8(dest, src, chars); 1480 MemCopyUint16Uint8(dest, src, chars);
1403 } else { 1481 } else {
1404 OS::MemCopyUint16Uint8Wrapper(dest, src, chars); 1482 MemCopyUint16Uint8Wrapper(dest, src, chars);
1405 } 1483 }
1406 } 1484 }
1407 1485
1408 1486
1409 void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) { 1487 void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
1410 switch (static_cast<unsigned>(chars)) { 1488 switch (static_cast<unsigned>(chars)) {
1411 case 0: 1489 case 0:
1412 break; 1490 break;
1413 case 1: 1491 case 1:
1414 *dest = *src; 1492 *dest = *src;
(...skipping 10 matching lines...) Expand all
1425 case 5: 1503 case 5:
1426 memcpy(dest, src, 10); 1504 memcpy(dest, src, 10);
1427 break; 1505 break;
1428 case 6: 1506 case 6:
1429 memcpy(dest, src, 12); 1507 memcpy(dest, src, 12);
1430 break; 1508 break;
1431 case 7: 1509 case 7:
1432 memcpy(dest, src, 14); 1510 memcpy(dest, src, 14);
1433 break; 1511 break;
1434 default: 1512 default:
1435 OS::MemCopy(dest, src, chars * sizeof(*dest)); 1513 MemCopy(dest, src, chars * sizeof(*dest));
1436 break; 1514 break;
1437 } 1515 }
1438 } 1516 }
1439 1517
1440 1518
1441 #elif defined(V8_HOST_ARCH_MIPS) 1519 #elif defined(V8_HOST_ARCH_MIPS)
1442 void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) { 1520 void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
1443 if (chars < OS::kMinComplexMemCopy) { 1521 if (chars < kMinComplexMemCopy) {
1444 memcpy(dest, src, chars); 1522 memcpy(dest, src, chars);
1445 } else { 1523 } else {
1446 OS::MemCopy(dest, src, chars); 1524 MemCopy(dest, src, chars);
1447 } 1525 }
1448 } 1526 }
1449 1527
1450 void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) { 1528 void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
1451 if (chars < OS::kMinComplexMemCopy) { 1529 if (chars < kMinComplexMemCopy) {
1452 memcpy(dest, src, chars * sizeof(*dest)); 1530 memcpy(dest, src, chars * sizeof(*dest));
1453 } else { 1531 } else {
1454 OS::MemCopy(dest, src, chars * sizeof(*dest)); 1532 MemCopy(dest, src, chars * sizeof(*dest));
1455 } 1533 }
1456 } 1534 }
1457 #endif 1535 #endif
1458 1536
1459 1537
1460 class StringBuilder : public SimpleStringBuilder { 1538 class StringBuilder : public SimpleStringBuilder {
1461 public: 1539 public:
1462 explicit StringBuilder(int size) : SimpleStringBuilder(size) { } 1540 explicit StringBuilder(int size) : SimpleStringBuilder(size) { }
1463 StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { } 1541 StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { }
1464 1542
1465 // Add formatted contents to the builder just like printf(). 1543 // Add formatted contents to the builder just like printf().
1466 void AddFormatted(const char* format, ...); 1544 void AddFormatted(const char* format, ...);
1467 1545
1468 // Add formatted contents like printf based on a va_list. 1546 // Add formatted contents like printf based on a va_list.
1469 void AddFormattedList(const char* format, va_list list); 1547 void AddFormattedList(const char* format, va_list list);
1470 private: 1548 private:
1471 DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); 1549 DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
1472 }; 1550 };
1473 1551
1474 1552
1475 } } // namespace v8::internal 1553 } } // namespace v8::internal
1476 1554
1477 #endif // V8_UTILS_H_ 1555 #endif // V8_UTILS_H_
OLDNEW
« no previous file with comments | « src/unicode-inl.h ('k') | src/utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698