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

Side by Side Diff: src/objects-inl.h

Issue 7477045: Tentative implementation of string slices (hidden under the flag --string-slices). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Some more suggested changes. Created 9 years, 4 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 // Because the symbol tag is non-zero and no non-string types have the 170 // Because the symbol tag is non-zero and no non-string types have the
171 // symbol bit set we can test for symbols with a very simple test 171 // symbol bit set we can test for symbols with a very simple test
172 // operation. 172 // operation.
173 ASSERT(kSymbolTag != 0); 173 ASSERT(kSymbolTag != 0);
174 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE); 174 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
175 return (type & kIsSymbolMask) != 0; 175 return (type & kIsSymbolMask) != 0;
176 } 176 }
177 177
178 178
179 bool Object::IsConsString() { 179 bool Object::IsConsString() {
180 if (!this->IsHeapObject()) return false; 180 if (!IsString()) return false;
181 uint32_t type = HeapObject::cast(this)->map()->instance_type(); 181 return StringShape(String::cast(this)).IsCons();
182 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
183 (kStringTag | kConsStringTag);
184 } 182 }
185 183
186 184
185 bool Object::IsSlicedString() {
186 if (!IsString()) return false;
187 return StringShape(String::cast(this)).IsSliced();
188 }
189
190
187 bool Object::IsSeqString() { 191 bool Object::IsSeqString() {
188 if (!IsString()) return false; 192 if (!IsString()) return false;
189 return StringShape(String::cast(this)).IsSequential(); 193 return StringShape(String::cast(this)).IsSequential();
190 } 194 }
191 195
192 196
193 bool Object::IsSeqAsciiString() { 197 bool Object::IsSeqAsciiString() {
194 if (!IsString()) return false; 198 if (!IsString()) return false;
195 return StringShape(String::cast(this)).IsSequential() && 199 return StringShape(String::cast(this)).IsSequential() &&
196 String::cast(this)->IsAsciiRepresentation(); 200 String::cast(this)->IsAsciiRepresentation();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 return (type & kStringEncodingMask) == kAsciiStringTag; 265 return (type & kStringEncodingMask) == kAsciiStringTag;
262 } 266 }
263 267
264 268
265 bool String::IsTwoByteRepresentation() { 269 bool String::IsTwoByteRepresentation() {
266 uint32_t type = map()->instance_type(); 270 uint32_t type = map()->instance_type();
267 return (type & kStringEncodingMask) == kTwoByteStringTag; 271 return (type & kStringEncodingMask) == kTwoByteStringTag;
268 } 272 }
269 273
270 274
275 bool String::IsAsciiRepresentationUnderneath() {
276 uint32_t type = map()->instance_type();
277 STATIC_ASSERT(kIsIndirectStringTag != 0);
278 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
279 ASSERT(IsFlat());
280 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
281 case kAsciiStringTag:
282 return true;
283 case kTwoByteStringTag:
284 return false;
285 default: // Cons or sliced string. Need to go deeper.
286 return GetUnderlying()->IsAsciiRepresentation();
287 }
288 }
289
290
291 bool String::IsTwoByteRepresentationUnderneath() {
292 uint32_t type = map()->instance_type();
293 STATIC_ASSERT(kIsIndirectStringTag != 0);
294 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
295 ASSERT(IsFlat());
296 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
297 case kAsciiStringTag:
298 return false;
299 case kTwoByteStringTag:
300 return true;
301 default: // Cons or sliced string. Need to go deeper.
302 return GetUnderlying()->IsTwoByteRepresentation();
303 }
304 }
305
306
271 bool String::HasOnlyAsciiChars() { 307 bool String::HasOnlyAsciiChars() {
272 uint32_t type = map()->instance_type(); 308 uint32_t type = map()->instance_type();
273 return (type & kStringEncodingMask) == kAsciiStringTag || 309 return (type & kStringEncodingMask) == kAsciiStringTag ||
274 (type & kAsciiDataHintMask) == kAsciiDataHintTag; 310 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
275 } 311 }
276 312
277 313
278 bool StringShape::IsCons() { 314 bool StringShape::IsCons() {
279 return (type_ & kStringRepresentationMask) == kConsStringTag; 315 return (type_ & kStringRepresentationMask) == kConsStringTag;
280 } 316 }
281 317
282 318
319 bool StringShape::IsSliced() {
320 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
321 }
322
323
324 bool StringShape::IsIndirect() {
325 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
326 }
327
328
283 bool StringShape::IsExternal() { 329 bool StringShape::IsExternal() {
284 return (type_ & kStringRepresentationMask) == kExternalStringTag; 330 return (type_ & kStringRepresentationMask) == kExternalStringTag;
285 } 331 }
286 332
287 333
288 bool StringShape::IsSequential() { 334 bool StringShape::IsSequential() {
289 return (type_ & kStringRepresentationMask) == kSeqStringTag; 335 return (type_ & kStringRepresentationMask) == kSeqStringTag;
290 } 336 }
291 337
292 338
(...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after
2023 CAST_ACCESSOR(JSFunctionResultCache) 2069 CAST_ACCESSOR(JSFunctionResultCache)
2024 CAST_ACCESSOR(NormalizedMapCache) 2070 CAST_ACCESSOR(NormalizedMapCache)
2025 CAST_ACCESSOR(CompilationCacheTable) 2071 CAST_ACCESSOR(CompilationCacheTable)
2026 CAST_ACCESSOR(CodeCacheHashTable) 2072 CAST_ACCESSOR(CodeCacheHashTable)
2027 CAST_ACCESSOR(PolymorphicCodeCacheHashTable) 2073 CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
2028 CAST_ACCESSOR(MapCache) 2074 CAST_ACCESSOR(MapCache)
2029 CAST_ACCESSOR(String) 2075 CAST_ACCESSOR(String)
2030 CAST_ACCESSOR(SeqString) 2076 CAST_ACCESSOR(SeqString)
2031 CAST_ACCESSOR(SeqAsciiString) 2077 CAST_ACCESSOR(SeqAsciiString)
2032 CAST_ACCESSOR(SeqTwoByteString) 2078 CAST_ACCESSOR(SeqTwoByteString)
2079 CAST_ACCESSOR(SlicedString)
2033 CAST_ACCESSOR(ConsString) 2080 CAST_ACCESSOR(ConsString)
2034 CAST_ACCESSOR(ExternalString) 2081 CAST_ACCESSOR(ExternalString)
2035 CAST_ACCESSOR(ExternalAsciiString) 2082 CAST_ACCESSOR(ExternalAsciiString)
2036 CAST_ACCESSOR(ExternalTwoByteString) 2083 CAST_ACCESSOR(ExternalTwoByteString)
2037 CAST_ACCESSOR(JSReceiver) 2084 CAST_ACCESSOR(JSReceiver)
2038 CAST_ACCESSOR(JSObject) 2085 CAST_ACCESSOR(JSObject)
2039 CAST_ACCESSOR(Smi) 2086 CAST_ACCESSOR(Smi)
2040 CAST_ACCESSOR(HeapObject) 2087 CAST_ACCESSOR(HeapObject)
2041 CAST_ACCESSOR(HeapNumber) 2088 CAST_ACCESSOR(HeapNumber)
2042 CAST_ACCESSOR(Oddball) 2089 CAST_ACCESSOR(Oddball)
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2109 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) { 2156 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2110 return false; 2157 return false;
2111 } 2158 }
2112 return SlowEquals(other); 2159 return SlowEquals(other);
2113 } 2160 }
2114 2161
2115 2162
2116 MaybeObject* String::TryFlatten(PretenureFlag pretenure) { 2163 MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
2117 if (!StringShape(this).IsCons()) return this; 2164 if (!StringShape(this).IsCons()) return this;
2118 ConsString* cons = ConsString::cast(this); 2165 ConsString* cons = ConsString::cast(this);
2119 if (cons->second()->length() == 0) return cons->first(); 2166 if (cons->IsFlat()) return cons->first();
2120 return SlowTryFlatten(pretenure); 2167 return SlowTryFlatten(pretenure);
2121 } 2168 }
2122 2169
2123 2170
2124 String* String::TryFlattenGetString(PretenureFlag pretenure) { 2171 String* String::TryFlattenGetString(PretenureFlag pretenure) {
2125 MaybeObject* flat = TryFlatten(pretenure); 2172 MaybeObject* flat = TryFlatten(pretenure);
2126 Object* successfully_flattened; 2173 Object* successfully_flattened;
2127 if (flat->ToObject(&successfully_flattened)) { 2174 if (!flat->ToObject(&successfully_flattened)) return this;
2128 return String::cast(successfully_flattened); 2175 return String::cast(successfully_flattened);
2129 }
2130 return this;
2131 } 2176 }
2132 2177
2133 2178
2134 uint16_t String::Get(int index) { 2179 uint16_t String::Get(int index) {
2135 ASSERT(index >= 0 && index < length()); 2180 ASSERT(index >= 0 && index < length());
2136 switch (StringShape(this).full_representation_tag()) { 2181 switch (StringShape(this).full_representation_tag()) {
2137 case kSeqStringTag | kAsciiStringTag: 2182 case kSeqStringTag | kAsciiStringTag:
2138 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index); 2183 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2139 case kSeqStringTag | kTwoByteStringTag: 2184 case kSeqStringTag | kTwoByteStringTag:
2140 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); 2185 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2141 case kConsStringTag | kAsciiStringTag: 2186 case kConsStringTag | kAsciiStringTag:
2142 case kConsStringTag | kTwoByteStringTag: 2187 case kConsStringTag | kTwoByteStringTag:
2143 return ConsString::cast(this)->ConsStringGet(index); 2188 return ConsString::cast(this)->ConsStringGet(index);
2144 case kExternalStringTag | kAsciiStringTag: 2189 case kExternalStringTag | kAsciiStringTag:
2145 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index); 2190 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2146 case kExternalStringTag | kTwoByteStringTag: 2191 case kExternalStringTag | kTwoByteStringTag:
2147 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); 2192 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
2193 case kSlicedStringTag | kAsciiStringTag:
2194 case kSlicedStringTag | kTwoByteStringTag:
2195 return SlicedString::cast(this)->SlicedStringGet(index);
2148 default: 2196 default:
2149 break; 2197 break;
2150 } 2198 }
2151 2199
2152 UNREACHABLE(); 2200 UNREACHABLE();
2153 return 0; 2201 return 0;
2154 } 2202 }
2155 2203
2156 2204
2157 void String::Set(int index, uint16_t value) { 2205 void String::Set(int index, uint16_t value) {
2158 ASSERT(index >= 0 && index < length()); 2206 ASSERT(index >= 0 && index < length());
2159 ASSERT(StringShape(this).IsSequential()); 2207 ASSERT(StringShape(this).IsSequential());
2160 2208
2161 return this->IsAsciiRepresentation() 2209 return this->IsAsciiRepresentation()
2162 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value) 2210 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2163 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value); 2211 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
2164 } 2212 }
2165 2213
2166 2214
2167 bool String::IsFlat() { 2215 bool String::IsFlat() {
2168 switch (StringShape(this).representation_tag()) { 2216 if (!StringShape(this).IsCons()) return true;
2169 case kConsStringTag: { 2217 return ConsString::cast(this)->second()->length() == 0;
2170 String* second = ConsString::cast(this)->second();
2171 // Only flattened strings have second part empty.
2172 return second->length() == 0;
2173 }
2174 default:
2175 return true;
2176 }
2177 } 2218 }
2178 2219
2179 2220
2221 String* String::GetUnderlying() {
2222 // Giving direct access to underlying string only makes sense if the
2223 // wrapping string is already flattened.
2224 ASSERT(this->IsFlat());
2225 ASSERT(StringShape(this).IsIndirect());
2226 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2227 const int kUnderlyingOffset = SlicedString::kParentOffset;
2228 return String::cast(READ_FIELD(this, kUnderlyingOffset));
2229 }
2230
2231
2180 uint16_t SeqAsciiString::SeqAsciiStringGet(int index) { 2232 uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
2181 ASSERT(index >= 0 && index < length()); 2233 ASSERT(index >= 0 && index < length());
2182 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); 2234 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2183 } 2235 }
2184 2236
2185 2237
2186 void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) { 2238 void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
2187 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode); 2239 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2188 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, 2240 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2189 static_cast<byte>(value)); 2241 static_cast<byte>(value));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) { 2277 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
2226 return SizeFor(length()); 2278 return SizeFor(length());
2227 } 2279 }
2228 2280
2229 2281
2230 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) { 2282 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
2231 return SizeFor(length()); 2283 return SizeFor(length());
2232 } 2284 }
2233 2285
2234 2286
2287 String* SlicedString::parent() {
2288 return String::cast(READ_FIELD(this, kParentOffset));
2289 }
2290
2291
2292 void SlicedString::set_parent(String* parent) {
2293 ASSERT(parent->IsSeqString());
2294 WRITE_FIELD(this, kParentOffset, parent);
2295 }
2296
2297
2298 SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2299
2300
2235 String* ConsString::first() { 2301 String* ConsString::first() {
2236 return String::cast(READ_FIELD(this, kFirstOffset)); 2302 return String::cast(READ_FIELD(this, kFirstOffset));
2237 } 2303 }
2238 2304
2239 2305
2240 Object* ConsString::unchecked_first() { 2306 Object* ConsString::unchecked_first() {
2241 return READ_FIELD(this, kFirstOffset); 2307 return READ_FIELD(this, kFirstOffset);
2242 } 2308 }
2243 2309
2244 2310
(...skipping 2255 matching lines...) Expand 10 before | Expand all | Expand 10 after
4500 #undef WRITE_INT_FIELD 4566 #undef WRITE_INT_FIELD
4501 #undef READ_SHORT_FIELD 4567 #undef READ_SHORT_FIELD
4502 #undef WRITE_SHORT_FIELD 4568 #undef WRITE_SHORT_FIELD
4503 #undef READ_BYTE_FIELD 4569 #undef READ_BYTE_FIELD
4504 #undef WRITE_BYTE_FIELD 4570 #undef WRITE_BYTE_FIELD
4505 4571
4506 4572
4507 } } // namespace v8::internal 4573 } } // namespace v8::internal
4508 4574
4509 #endif // V8_OBJECTS_INL_H_ 4575 #endif // V8_OBJECTS_INL_H_
OLDNEW
« src/ia32/code-stubs-ia32.cc ('K') | « src/objects-debug.cc ('k') | src/objects-visiting.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698