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 4286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4297 | 4297 |
4298 bool String::IsOneByte() const { | 4298 bool String::IsOneByte() const { |
4299 i::Handle<i::String> str = Utils::OpenHandle(this); | 4299 i::Handle<i::String> str = Utils::OpenHandle(this); |
4300 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsOneByte()")) { | 4300 if (IsDeadCheck(str->GetIsolate(), "v8::String::IsOneByte()")) { |
4301 return false; | 4301 return false; |
4302 } | 4302 } |
4303 return str->HasOnlyOneByteChars(); | 4303 return str->HasOnlyOneByteChars(); |
4304 } | 4304 } |
4305 | 4305 |
4306 | 4306 |
4307 // Helpers for ContainsOnlyOneByteHelper | |
4308 template<size_t size> struct OneByteMask; | |
4309 template<> struct OneByteMask<4> { | |
4310 static const uint32_t value = 0xFF00FF00U; | |
4311 }; | |
4312 template<> struct OneByteMask<8> { | |
4313 static const uint64_t value = 0xFF00FF00FF00ULL; | |
Yang
2013/06/07 09:19:06
Shouldn't this be 0xFF00FF00FF00FF00ULL (missing o
| |
4314 }; | |
4315 static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value; | |
Yang
2013/06/07 09:19:06
I guess you could also just static_cast<uintptr_t>
| |
4316 static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1; | |
4317 static inline bool Unaligned(const uint16_t* chars) { | |
4318 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask; | |
4319 } | |
4320 static inline const uint16_t* Align(const uint16_t* chars) { | |
4321 return reinterpret_cast<uint16_t*>( | |
4322 reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask); | |
4323 } | |
4324 | |
4325 | |
4307 class ContainsOnlyOneByteHelper { | 4326 class ContainsOnlyOneByteHelper { |
4308 public: | 4327 public: |
4309 ContainsOnlyOneByteHelper() : is_one_byte_(true) {} | 4328 ContainsOnlyOneByteHelper() : is_one_byte_(true) {} |
4310 bool Check(i::String* string) { | 4329 bool Check(i::String* string) { |
4311 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0); | 4330 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0); |
4312 if (cons_string == NULL) return is_one_byte_; | 4331 if (cons_string == NULL) return is_one_byte_; |
4313 return CheckCons(cons_string); | 4332 return CheckCons(cons_string); |
4314 } | 4333 } |
4315 void VisitOneByteString(const uint8_t* chars, int length) { | 4334 void VisitOneByteString(const uint8_t* chars, int length) { |
4316 // Nothing to do. | 4335 // Nothing to do. |
4317 } | 4336 } |
4318 // TODO(dcarney): do word aligned read. | |
4319 void VisitTwoByteString(const uint16_t* chars, int length) { | 4337 void VisitTwoByteString(const uint16_t* chars, int length) { |
4320 // Check whole string without breaking. | 4338 // Accumulated bits. |
4321 uint16_t total = 0; | 4339 uintptr_t acc = 0; |
4322 for (int i = 0; i < length; i++) { | 4340 // Align to uintptr_t. |
4323 total |= chars[i] >> 8; | 4341 const uint16_t* end = chars + length; |
4342 while (Unaligned(chars) && chars != end) { | |
4343 acc |= *chars++; | |
4324 } | 4344 } |
4325 if (total != 0) is_one_byte_ = false; | 4345 // Read word aligned in blocks, |
4346 // checking the return value at the end of each block. | |
4347 const uint16_t* aligned_end = Align(end); | |
4348 const int increment = sizeof(uintptr_t)/sizeof(uint16_t); | |
4349 const int inner_loops = 16; | |
4350 while (chars + inner_loops*increment < aligned_end) { | |
4351 for (int i = 0; i < inner_loops; i++) { | |
4352 acc |= *reinterpret_cast<const uintptr_t*>(chars); | |
4353 chars += increment; | |
4354 } | |
4355 // Check for early return. | |
4356 if ((acc & kOneByteMask) != 0) { | |
4357 is_one_byte_ = false; | |
4358 return; | |
4359 } | |
4360 } | |
4361 // Read the rest. | |
4362 while (chars != end) { | |
4363 acc |= *chars++; | |
4364 } | |
4365 // Check result. | |
4366 if ((acc & kOneByteMask) != 0) is_one_byte_ = false; | |
4326 } | 4367 } |
4327 | 4368 |
4328 private: | 4369 private: |
4329 bool CheckCons(i::ConsString* cons_string) { | 4370 bool CheckCons(i::ConsString* cons_string) { |
4330 while (true) { | 4371 while (true) { |
4331 // Check left side if flat. | 4372 // Check left side if flat. |
4332 i::String* left = cons_string->first(); | 4373 i::String* left = cons_string->first(); |
4333 i::ConsString* left_as_cons = | 4374 i::ConsString* left_as_cons = |
4334 i::String::VisitFlat(this, left, 0); | 4375 i::String::VisitFlat(this, left, 0); |
4335 if (!is_one_byte_) return false; | 4376 if (!is_one_byte_) return false; |
(...skipping 3598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7934 | 7975 |
7935 v->VisitPointers(blocks_.first(), first_block_limit_); | 7976 v->VisitPointers(blocks_.first(), first_block_limit_); |
7936 | 7977 |
7937 for (int i = 1; i < blocks_.length(); i++) { | 7978 for (int i = 1; i < blocks_.length(); i++) { |
7938 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); | 7979 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); |
7939 } | 7980 } |
7940 } | 7981 } |
7941 | 7982 |
7942 | 7983 |
7943 } } // namespace v8::internal | 7984 } } // namespace v8::internal |
OLD | NEW |