OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 4297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4308 public: | 4308 public: |
4309 ContainsOnlyOneByteHelper() : is_one_byte_(true) {} | 4309 ContainsOnlyOneByteHelper() : is_one_byte_(true) {} |
4310 bool Check(i::String* string) { | 4310 bool Check(i::String* string) { |
4311 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0); | 4311 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0); |
4312 if (cons_string == NULL) return is_one_byte_; | 4312 if (cons_string == NULL) return is_one_byte_; |
4313 return CheckCons(cons_string); | 4313 return CheckCons(cons_string); |
4314 } | 4314 } |
4315 void VisitOneByteString(const uint8_t* chars, int length) { | 4315 void VisitOneByteString(const uint8_t* chars, int length) { |
4316 // Nothing to do. | 4316 // Nothing to do. |
4317 } | 4317 } |
4318 // TODO(dcarney): do word aligned read. | |
4319 void VisitTwoByteString(const uint16_t* chars, int length) { | 4318 void VisitTwoByteString(const uint16_t* chars, int length) { |
4320 // Check whole string without breaking. | 4319 // Accumulated bits. |
4321 uint16_t total = 0; | 4320 uintptr_t acc = 0; |
4322 for (int i = 0; i < length; i++) { | 4321 // Align to uintptr_t. |
4323 total |= chars[i] >> 8; | 4322 const uint16_t* end = chars + length; |
| 4323 while (Unaligned(chars) && chars != end) { |
| 4324 acc |= *chars++; |
4324 } | 4325 } |
4325 if (total != 0) is_one_byte_ = false; | 4326 // Read word aligned in blocks, |
| 4327 // checking the return value at the end of each block. |
| 4328 const uint16_t* aligned_end = Align(end); |
| 4329 const int increment = sizeof(uintptr_t)/sizeof(uint16_t); |
| 4330 const int inner_loops = 16; |
| 4331 while (chars + inner_loops*increment < aligned_end) { |
| 4332 for (int i = 0; i < inner_loops; i++) { |
| 4333 acc |= *reinterpret_cast<const uintptr_t*>(chars); |
| 4334 chars += increment; |
| 4335 } |
| 4336 // Check for early return. |
| 4337 if ((acc & kOneByteMask) != 0) { |
| 4338 is_one_byte_ = false; |
| 4339 return; |
| 4340 } |
| 4341 } |
| 4342 // Read the rest. |
| 4343 while (chars != end) { |
| 4344 acc |= *chars++; |
| 4345 } |
| 4346 // Check result. |
| 4347 if ((acc & kOneByteMask) != 0) is_one_byte_ = false; |
4326 } | 4348 } |
4327 | 4349 |
4328 private: | 4350 private: |
| 4351 static const uintptr_t kOneByteMask = |
| 4352 static_cast<uintptr_t>(0xFF00FF00FF00FF00ULL); |
| 4353 static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1; |
| 4354 static inline bool Unaligned(const uint16_t* chars) { |
| 4355 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask; |
| 4356 } |
| 4357 static inline const uint16_t* Align(const uint16_t* chars) { |
| 4358 return reinterpret_cast<uint16_t*>( |
| 4359 reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask); |
| 4360 } |
4329 bool CheckCons(i::ConsString* cons_string) { | 4361 bool CheckCons(i::ConsString* cons_string) { |
4330 while (true) { | 4362 while (true) { |
4331 // Check left side if flat. | 4363 // Check left side if flat. |
4332 i::String* left = cons_string->first(); | 4364 i::String* left = cons_string->first(); |
4333 i::ConsString* left_as_cons = | 4365 i::ConsString* left_as_cons = |
4334 i::String::VisitFlat(this, left, 0); | 4366 i::String::VisitFlat(this, left, 0); |
4335 if (!is_one_byte_) return false; | 4367 if (!is_one_byte_) return false; |
4336 // Check right side if flat. | 4368 // Check right side if flat. |
4337 i::String* right = cons_string->second(); | 4369 i::String* right = cons_string->second(); |
4338 i::ConsString* right_as_cons = | 4370 i::ConsString* right_as_cons = |
(...skipping 3617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7956 | 7988 |
7957 v->VisitPointers(blocks_.first(), first_block_limit_); | 7989 v->VisitPointers(blocks_.first(), first_block_limit_); |
7958 | 7990 |
7959 for (int i = 1; i < blocks_.length(); i++) { | 7991 for (int i = 1; i < blocks_.length(); i++) { |
7960 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); | 7992 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); |
7961 } | 7993 } |
7962 } | 7994 } |
7963 | 7995 |
7964 | 7996 |
7965 } } // namespace v8::internal | 7997 } } // namespace v8::internal |
OLD | NEW |