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

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: Patched RegExp for string slices. 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 return (type & kStringEncodingMask) == kAsciiStringTag || 277 return (type & kStringEncodingMask) == kAsciiStringTag ||
274 (type & kAsciiDataHintMask) == kAsciiDataHintTag; 278 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
275 } 279 }
276 280
277 281
278 bool StringShape::IsCons() { 282 bool StringShape::IsCons() {
279 return (type_ & kStringRepresentationMask) == kConsStringTag; 283 return (type_ & kStringRepresentationMask) == kConsStringTag;
280 } 284 }
281 285
282 286
287 bool StringShape::IsSliced() {
288 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
289 }
290
291
292 bool StringShape::IsIndirect() {
293 ASSERT(((type_ & kIsIndirectStringMask) == kIsIndirectStringTag)
294 == (((type_ & kStringRepresentationMask) == kConsStringTag)
295 || ((type_ & kStringRepresentationMask) == kSlicedStringTag)));
antonm 2011/08/04 12:18:48 Isn't it similar to change to Heap::TargetSpaceId?
296 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
297 }
Yang 2011/08/04 09:19:53 Being 'indirect' means either cons or slice. Acces
298
299
283 bool StringShape::IsExternal() { 300 bool StringShape::IsExternal() {
284 return (type_ & kStringRepresentationMask) == kExternalStringTag; 301 return (type_ & kStringRepresentationMask) == kExternalStringTag;
285 } 302 }
286 303
287 304
288 bool StringShape::IsSequential() { 305 bool StringShape::IsSequential() {
289 return (type_ & kStringRepresentationMask) == kSeqStringTag; 306 return (type_ & kStringRepresentationMask) == kSeqStringTag;
290 } 307 }
291 308
292 309
(...skipping 1741 matching lines...) Expand 10 before | Expand all | Expand 10 after
2034 CAST_ACCESSOR(JSFunctionResultCache) 2051 CAST_ACCESSOR(JSFunctionResultCache)
2035 CAST_ACCESSOR(NormalizedMapCache) 2052 CAST_ACCESSOR(NormalizedMapCache)
2036 CAST_ACCESSOR(CompilationCacheTable) 2053 CAST_ACCESSOR(CompilationCacheTable)
2037 CAST_ACCESSOR(CodeCacheHashTable) 2054 CAST_ACCESSOR(CodeCacheHashTable)
2038 CAST_ACCESSOR(PolymorphicCodeCacheHashTable) 2055 CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
2039 CAST_ACCESSOR(MapCache) 2056 CAST_ACCESSOR(MapCache)
2040 CAST_ACCESSOR(String) 2057 CAST_ACCESSOR(String)
2041 CAST_ACCESSOR(SeqString) 2058 CAST_ACCESSOR(SeqString)
2042 CAST_ACCESSOR(SeqAsciiString) 2059 CAST_ACCESSOR(SeqAsciiString)
2043 CAST_ACCESSOR(SeqTwoByteString) 2060 CAST_ACCESSOR(SeqTwoByteString)
2061 CAST_ACCESSOR(SlicedString)
2044 CAST_ACCESSOR(ConsString) 2062 CAST_ACCESSOR(ConsString)
2045 CAST_ACCESSOR(ExternalString) 2063 CAST_ACCESSOR(ExternalString)
2046 CAST_ACCESSOR(ExternalAsciiString) 2064 CAST_ACCESSOR(ExternalAsciiString)
2047 CAST_ACCESSOR(ExternalTwoByteString) 2065 CAST_ACCESSOR(ExternalTwoByteString)
2048 CAST_ACCESSOR(JSReceiver) 2066 CAST_ACCESSOR(JSReceiver)
2049 CAST_ACCESSOR(JSObject) 2067 CAST_ACCESSOR(JSObject)
2050 CAST_ACCESSOR(Smi) 2068 CAST_ACCESSOR(Smi)
2051 CAST_ACCESSOR(HeapObject) 2069 CAST_ACCESSOR(HeapObject)
2052 CAST_ACCESSOR(HeapNumber) 2070 CAST_ACCESSOR(HeapNumber)
2053 CAST_ACCESSOR(Oddball) 2071 CAST_ACCESSOR(Oddball)
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2120 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) { 2138 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2121 return false; 2139 return false;
2122 } 2140 }
2123 return SlowEquals(other); 2141 return SlowEquals(other);
2124 } 2142 }
2125 2143
2126 2144
2127 MaybeObject* String::TryFlatten(PretenureFlag pretenure) { 2145 MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
2128 if (!StringShape(this).IsCons()) return this; 2146 if (!StringShape(this).IsCons()) return this;
2129 ConsString* cons = ConsString::cast(this); 2147 ConsString* cons = ConsString::cast(this);
2130 if (cons->second()->length() == 0) return cons->first(); 2148 if (cons->IsFlat()) return cons->first();
2131 return SlowTryFlatten(pretenure); 2149 return SlowTryFlatten(pretenure);
2132 } 2150 }
2133 2151
2134 2152
2135 String* String::TryFlattenGetString(PretenureFlag pretenure) { 2153 String* String::TryFlattenGetString(PretenureFlag pretenure) {
2136 MaybeObject* flat = TryFlatten(pretenure); 2154 MaybeObject* flat = TryFlatten(pretenure);
2137 Object* successfully_flattened; 2155 Object* successfully_flattened;
2138 if (flat->ToObject(&successfully_flattened)) { 2156 if (!flat->ToObject(&successfully_flattened)) return this;
2139 return String::cast(successfully_flattened); 2157 return String::cast(successfully_flattened);
2140 }
2141 return this;
2142 } 2158 }
2143 2159
2144 2160
2161 MaybeObject* String::TryTruncate(PretenureFlag pretenure) {
2162 if (!StringShape(this).IsSliced()) return this;
2163 SlicedString* slice = SlicedString::cast(this);
2164 if (slice->IsTruncated()) return slice->parent();
2165 return SlowTryTruncate(pretenure);
2166 }
2167
2168
2169 String* String::TryTruncateGetString(PretenureFlag pretenure) {
2170 MaybeObject* truncate = TryTruncate(pretenure);
2171 Object* successfully_truncated;
2172 if (!truncate->ToObject(&successfully_truncated)) return this;
2173 return String::cast(successfully_truncated);
2174 }
2175
2176
2177 MaybeObject* String::TryFlattenOrTruncate(PretenureFlag pretenure) {
2178 switch (StringShape(this).representation_tag()) {
2179 case kSlicedStringTag: {
2180 SlicedString* slice = SlicedString::cast(this);
2181 if (slice->IsTruncated()) return slice->parent();
2182 return SlowTryTruncate(pretenure);
2183 }
2184 case kConsStringTag: {
2185 ConsString* cons = ConsString::cast(this);
2186 if (cons->IsFlat()) return cons->first();
2187 return SlowTryFlatten(pretenure);
2188 }
2189 default:
2190 return this;
2191 }
2192 }
2193
2194
2145 uint16_t String::Get(int index) { 2195 uint16_t String::Get(int index) {
2146 ASSERT(index >= 0 && index < length()); 2196 ASSERT(index >= 0 && index < length());
2147 switch (StringShape(this).full_representation_tag()) { 2197 switch (StringShape(this).full_representation_tag()) {
2148 case kSeqStringTag | kAsciiStringTag: 2198 case kSeqStringTag | kAsciiStringTag:
2149 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index); 2199 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2150 case kSeqStringTag | kTwoByteStringTag: 2200 case kSeqStringTag | kTwoByteStringTag:
2151 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); 2201 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2152 case kConsStringTag | kAsciiStringTag: 2202 case kConsStringTag | kAsciiStringTag:
2153 case kConsStringTag | kTwoByteStringTag: 2203 case kConsStringTag | kTwoByteStringTag:
2154 return ConsString::cast(this)->ConsStringGet(index); 2204 return ConsString::cast(this)->ConsStringGet(index);
2155 case kExternalStringTag | kAsciiStringTag: 2205 case kExternalStringTag | kAsciiStringTag:
2156 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index); 2206 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2157 case kExternalStringTag | kTwoByteStringTag: 2207 case kExternalStringTag | kTwoByteStringTag:
2158 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); 2208 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
2209 case kSlicedStringTag | kAsciiStringTag:
2210 case kSlicedStringTag | kTwoByteStringTag:
2211 return SlicedString::cast(this)->SlicedStringGet(index);
2159 default: 2212 default:
2160 break; 2213 break;
2161 } 2214 }
2162 2215
2163 UNREACHABLE(); 2216 UNREACHABLE();
2164 return 0; 2217 return 0;
2165 } 2218 }
2166 2219
2167 2220
2168 void String::Set(int index, uint16_t value) { 2221 void String::Set(int index, uint16_t value) {
2169 ASSERT(index >= 0 && index < length()); 2222 ASSERT(index >= 0 && index < length());
2170 ASSERT(StringShape(this).IsSequential()); 2223 ASSERT(StringShape(this).IsSequential());
2171 2224
2172 return this->IsAsciiRepresentation() 2225 return this->IsAsciiRepresentation()
2173 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value) 2226 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2174 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value); 2227 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
2175 } 2228 }
2176 2229
2177 2230
2178 bool String::IsFlat() { 2231 bool String::IsFlat() {
2232 if (!StringShape(this).IsCons()) return true;
2233 return ConsString::cast(this)->second() == GetHeap()->empty_string();
2234 }
2235
2236
2237 bool String::IsTruncated() {
2238 if (!StringShape(this).IsSliced()) return true;
2239 SlicedString* slice = SlicedString::cast(this);
2240 return slice->parent()->length() == slice->length();
2241 }
2242
2243
2244 bool String::IsFlatAndTruncated() {
2179 switch (StringShape(this).representation_tag()) { 2245 switch (StringShape(this).representation_tag()) {
2180 case kConsStringTag: { 2246 case kSlicedStringTag: {
2181 String* second = ConsString::cast(this)->second(); 2247 SlicedString* slice = SlicedString::cast(this);
2182 // Only flattened strings have second part empty. 2248 return slice->parent()->length() == slice->length();
2183 return second->length() == 0;
2184 } 2249 }
2250 case kConsStringTag:
2251 return ConsString::cast(this)->second() == GetHeap()->empty_string();
2185 default: 2252 default:
2186 return true; 2253 return true;
2187 } 2254 }
2188 } 2255 }
2189 2256
2190 2257
2258 String* String::GetIndirect() {
2259 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2260 ASSERT(this->IsFlat());
2261 ASSERT(this->IsTruncated());
2262 ASSERT(StringShape(this).IsIndirect());
2263 return String::cast(reinterpret_cast<ConsString*>(this)->first());
2264 }
2265
2266
2191 uint16_t SeqAsciiString::SeqAsciiStringGet(int index) { 2267 uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
2192 ASSERT(index >= 0 && index < length()); 2268 ASSERT(index >= 0 && index < length());
2193 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); 2269 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2194 } 2270 }
2195 2271
2196 2272
2197 void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) { 2273 void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
2198 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode); 2274 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2199 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, 2275 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2200 static_cast<byte>(value)); 2276 static_cast<byte>(value));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2236 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) { 2312 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
2237 return SizeFor(length()); 2313 return SizeFor(length());
2238 } 2314 }
2239 2315
2240 2316
2241 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) { 2317 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
2242 return SizeFor(length()); 2318 return SizeFor(length());
2243 } 2319 }
2244 2320
2245 2321
2322 String* SlicedString::parent() {
2323 return String::cast(READ_FIELD(this, kParentOffset));
2324 }
2325
2326
2327 void SlicedString::set_parent(String* parent) {
2328 ASSERT(parent->IsSeqString());
2329 WRITE_FIELD(this, kParentOffset, parent);
2330 }
2331
2332
2333 SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2334
2335
2246 String* ConsString::first() { 2336 String* ConsString::first() {
2247 return String::cast(READ_FIELD(this, kFirstOffset)); 2337 return String::cast(READ_FIELD(this, kFirstOffset));
2248 } 2338 }
2249 2339
2250 2340
2251 Object* ConsString::unchecked_first() { 2341 Object* ConsString::unchecked_first() {
2252 return READ_FIELD(this, kFirstOffset); 2342 return READ_FIELD(this, kFirstOffset);
2253 } 2343 }
2254 2344
2255 2345
(...skipping 2255 matching lines...) Expand 10 before | Expand all | Expand 10 after
4511 #undef WRITE_INT_FIELD 4601 #undef WRITE_INT_FIELD
4512 #undef READ_SHORT_FIELD 4602 #undef READ_SHORT_FIELD
4513 #undef WRITE_SHORT_FIELD 4603 #undef WRITE_SHORT_FIELD
4514 #undef READ_BYTE_FIELD 4604 #undef READ_BYTE_FIELD
4515 #undef WRITE_BYTE_FIELD 4605 #undef WRITE_BYTE_FIELD
4516 4606
4517 4607
4518 } } // namespace v8::internal 4608 } } // namespace v8::internal
4519 4609
4520 #endif // V8_OBJECTS_INL_H_ 4610 #endif // V8_OBJECTS_INL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698