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

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

Issue 7860035: Merge bleeding edge up to 9192 into the GC branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Created 9 years, 3 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/objects-debug.cc ('k') | src/objects-visiting.h » ('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 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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE; 173 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
174 } 174 }
175 175
176 176
177 bool Object::IsSymbol() { 177 bool Object::IsSymbol() {
178 if (!this->IsHeapObject()) return false; 178 if (!this->IsHeapObject()) return false;
179 uint32_t type = HeapObject::cast(this)->map()->instance_type(); 179 uint32_t type = HeapObject::cast(this)->map()->instance_type();
180 // Because the symbol tag is non-zero and no non-string types have the 180 // Because the symbol tag is non-zero and no non-string types have the
181 // symbol bit set we can test for symbols with a very simple test 181 // symbol bit set we can test for symbols with a very simple test
182 // operation. 182 // operation.
183 ASSERT(kSymbolTag != 0); 183 STATIC_ASSERT(kSymbolTag != 0);
184 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE); 184 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
185 return (type & kIsSymbolMask) != 0; 185 return (type & kIsSymbolMask) != 0;
186 } 186 }
187 187
188 188
189 bool Object::IsConsString() { 189 bool Object::IsConsString() {
190 if (!this->IsHeapObject()) return false; 190 if (!IsString()) return false;
191 uint32_t type = HeapObject::cast(this)->map()->instance_type(); 191 return StringShape(String::cast(this)).IsCons();
192 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
193 (kStringTag | kConsStringTag);
194 } 192 }
195 193
196 194
195 bool Object::IsSlicedString() {
196 if (!IsString()) return false;
197 return StringShape(String::cast(this)).IsSliced();
198 }
199
200
197 bool Object::IsSeqString() { 201 bool Object::IsSeqString() {
198 if (!IsString()) return false; 202 if (!IsString()) return false;
199 return StringShape(String::cast(this)).IsSequential(); 203 return StringShape(String::cast(this)).IsSequential();
200 } 204 }
201 205
202 206
203 bool Object::IsSeqAsciiString() { 207 bool Object::IsSeqAsciiString() {
204 if (!IsString()) return false; 208 if (!IsString()) return false;
205 return StringShape(String::cast(this)).IsSequential() && 209 return StringShape(String::cast(this)).IsSequential() &&
206 String::cast(this)->IsAsciiRepresentation(); 210 String::cast(this)->IsAsciiRepresentation();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 258
255 StringShape::StringShape(InstanceType t) 259 StringShape::StringShape(InstanceType t)
256 : type_(static_cast<uint32_t>(t)) { 260 : type_(static_cast<uint32_t>(t)) {
257 set_valid(); 261 set_valid();
258 ASSERT((type_ & kIsNotStringMask) == kStringTag); 262 ASSERT((type_ & kIsNotStringMask) == kStringTag);
259 } 263 }
260 264
261 265
262 bool StringShape::IsSymbol() { 266 bool StringShape::IsSymbol() {
263 ASSERT(valid()); 267 ASSERT(valid());
264 ASSERT(kSymbolTag != 0); 268 STATIC_ASSERT(kSymbolTag != 0);
265 return (type_ & kIsSymbolMask) != 0; 269 return (type_ & kIsSymbolMask) != 0;
266 } 270 }
267 271
268 272
269 bool String::IsAsciiRepresentation() { 273 bool String::IsAsciiRepresentation() {
270 uint32_t type = map()->instance_type(); 274 uint32_t type = map()->instance_type();
271 return (type & kStringEncodingMask) == kAsciiStringTag; 275 return (type & kStringEncodingMask) == kAsciiStringTag;
272 } 276 }
273 277
274 278
275 bool String::IsTwoByteRepresentation() { 279 bool String::IsTwoByteRepresentation() {
276 uint32_t type = map()->instance_type(); 280 uint32_t type = map()->instance_type();
277 return (type & kStringEncodingMask) == kTwoByteStringTag; 281 return (type & kStringEncodingMask) == kTwoByteStringTag;
278 } 282 }
279 283
280 284
285 bool String::IsAsciiRepresentationUnderneath() {
286 uint32_t type = map()->instance_type();
287 STATIC_ASSERT(kIsIndirectStringTag != 0);
288 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
289 ASSERT(IsFlat());
290 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
291 case kAsciiStringTag:
292 return true;
293 case kTwoByteStringTag:
294 return false;
295 default: // Cons or sliced string. Need to go deeper.
296 return GetUnderlying()->IsAsciiRepresentation();
297 }
298 }
299
300
301 bool String::IsTwoByteRepresentationUnderneath() {
302 uint32_t type = map()->instance_type();
303 STATIC_ASSERT(kIsIndirectStringTag != 0);
304 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
305 ASSERT(IsFlat());
306 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
307 case kAsciiStringTag:
308 return false;
309 case kTwoByteStringTag:
310 return true;
311 default: // Cons or sliced string. Need to go deeper.
312 return GetUnderlying()->IsTwoByteRepresentation();
313 }
314 }
315
316
281 bool String::HasOnlyAsciiChars() { 317 bool String::HasOnlyAsciiChars() {
282 uint32_t type = map()->instance_type(); 318 uint32_t type = map()->instance_type();
283 return (type & kStringEncodingMask) == kAsciiStringTag || 319 return (type & kStringEncodingMask) == kAsciiStringTag ||
284 (type & kAsciiDataHintMask) == kAsciiDataHintTag; 320 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
285 } 321 }
286 322
287 323
288 bool StringShape::IsCons() { 324 bool StringShape::IsCons() {
289 return (type_ & kStringRepresentationMask) == kConsStringTag; 325 return (type_ & kStringRepresentationMask) == kConsStringTag;
290 } 326 }
291 327
292 328
329 bool StringShape::IsSliced() {
330 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
331 }
332
333
334 bool StringShape::IsIndirect() {
335 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
336 }
337
338
293 bool StringShape::IsExternal() { 339 bool StringShape::IsExternal() {
294 return (type_ & kStringRepresentationMask) == kExternalStringTag; 340 return (type_ & kStringRepresentationMask) == kExternalStringTag;
295 } 341 }
296 342
297 343
298 bool StringShape::IsSequential() { 344 bool StringShape::IsSequential() {
299 return (type_ & kStringRepresentationMask) == kSeqStringTag; 345 return (type_ & kStringRepresentationMask) == kSeqStringTag;
300 } 346 }
301 347
302 348
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1600 1646
1601 bool FixedDoubleArray::is_the_hole(int index) { 1647 bool FixedDoubleArray::is_the_hole(int index) {
1602 int offset = kHeaderSize + index * kDoubleSize; 1648 int offset = kHeaderSize + index * kDoubleSize;
1603 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset)); 1649 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1604 } 1650 }
1605 1651
1606 1652
1607 void FixedDoubleArray::Initialize(FixedDoubleArray* from) { 1653 void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1608 int old_length = from->length(); 1654 int old_length = from->length();
1609 ASSERT(old_length < length()); 1655 ASSERT(old_length < length());
1610 OS::MemCopy(FIELD_ADDR(this, kHeaderSize), 1656 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1611 FIELD_ADDR(from, kHeaderSize), 1657 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1612 old_length * kDoubleSize); 1658 FIELD_ADDR(from, kHeaderSize),
1659 old_length * kDoubleSize);
1660 } else {
1661 for (int i = 0; i < old_length; ++i) {
1662 set(i, from->get_scalar(i));
1663 }
1664 }
1613 int offset = kHeaderSize + old_length * kDoubleSize; 1665 int offset = kHeaderSize + old_length * kDoubleSize;
1614 for (int current = from->length(); current < length(); ++current) { 1666 for (int current = from->length(); current < length(); ++current) {
1615 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double()); 1667 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1616 offset += kDoubleSize; 1668 offset += kDoubleSize;
1617 } 1669 }
1618 } 1670 }
1619 1671
1620 1672
1621 void FixedDoubleArray::Initialize(FixedArray* from) { 1673 void FixedDoubleArray::Initialize(FixedArray* from) {
1622 int old_length = from->length(); 1674 int old_length = from->length();
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1978 CAST_ACCESSOR(JSFunctionResultCache) 2030 CAST_ACCESSOR(JSFunctionResultCache)
1979 CAST_ACCESSOR(NormalizedMapCache) 2031 CAST_ACCESSOR(NormalizedMapCache)
1980 CAST_ACCESSOR(CompilationCacheTable) 2032 CAST_ACCESSOR(CompilationCacheTable)
1981 CAST_ACCESSOR(CodeCacheHashTable) 2033 CAST_ACCESSOR(CodeCacheHashTable)
1982 CAST_ACCESSOR(PolymorphicCodeCacheHashTable) 2034 CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
1983 CAST_ACCESSOR(MapCache) 2035 CAST_ACCESSOR(MapCache)
1984 CAST_ACCESSOR(String) 2036 CAST_ACCESSOR(String)
1985 CAST_ACCESSOR(SeqString) 2037 CAST_ACCESSOR(SeqString)
1986 CAST_ACCESSOR(SeqAsciiString) 2038 CAST_ACCESSOR(SeqAsciiString)
1987 CAST_ACCESSOR(SeqTwoByteString) 2039 CAST_ACCESSOR(SeqTwoByteString)
2040 CAST_ACCESSOR(SlicedString)
1988 CAST_ACCESSOR(ConsString) 2041 CAST_ACCESSOR(ConsString)
1989 CAST_ACCESSOR(ExternalString) 2042 CAST_ACCESSOR(ExternalString)
1990 CAST_ACCESSOR(ExternalAsciiString) 2043 CAST_ACCESSOR(ExternalAsciiString)
1991 CAST_ACCESSOR(ExternalTwoByteString) 2044 CAST_ACCESSOR(ExternalTwoByteString)
1992 CAST_ACCESSOR(JSReceiver) 2045 CAST_ACCESSOR(JSReceiver)
1993 CAST_ACCESSOR(JSObject) 2046 CAST_ACCESSOR(JSObject)
1994 CAST_ACCESSOR(Smi) 2047 CAST_ACCESSOR(Smi)
1995 CAST_ACCESSOR(HeapObject) 2048 CAST_ACCESSOR(HeapObject)
1996 CAST_ACCESSOR(HeapNumber) 2049 CAST_ACCESSOR(HeapNumber)
1997 CAST_ACCESSOR(Oddball) 2050 CAST_ACCESSOR(Oddball)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2061 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) { 2114 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2062 return false; 2115 return false;
2063 } 2116 }
2064 return SlowEquals(other); 2117 return SlowEquals(other);
2065 } 2118 }
2066 2119
2067 2120
2068 MaybeObject* String::TryFlatten(PretenureFlag pretenure) { 2121 MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
2069 if (!StringShape(this).IsCons()) return this; 2122 if (!StringShape(this).IsCons()) return this;
2070 ConsString* cons = ConsString::cast(this); 2123 ConsString* cons = ConsString::cast(this);
2071 if (cons->second()->length() == 0) return cons->first(); 2124 if (cons->IsFlat()) return cons->first();
2072 return SlowTryFlatten(pretenure); 2125 return SlowTryFlatten(pretenure);
2073 } 2126 }
2074 2127
2075 2128
2076 String* String::TryFlattenGetString(PretenureFlag pretenure) { 2129 String* String::TryFlattenGetString(PretenureFlag pretenure) {
2077 MaybeObject* flat = TryFlatten(pretenure); 2130 MaybeObject* flat = TryFlatten(pretenure);
2078 Object* successfully_flattened; 2131 Object* successfully_flattened;
2079 if (flat->ToObject(&successfully_flattened)) { 2132 if (!flat->ToObject(&successfully_flattened)) return this;
2080 return String::cast(successfully_flattened); 2133 return String::cast(successfully_flattened);
2081 }
2082 return this;
2083 } 2134 }
2084 2135
2085 2136
2086 uint16_t String::Get(int index) { 2137 uint16_t String::Get(int index) {
2087 ASSERT(index >= 0 && index < length()); 2138 ASSERT(index >= 0 && index < length());
2088 switch (StringShape(this).full_representation_tag()) { 2139 switch (StringShape(this).full_representation_tag()) {
2089 case kSeqStringTag | kAsciiStringTag: 2140 case kSeqStringTag | kAsciiStringTag:
2090 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index); 2141 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2091 case kSeqStringTag | kTwoByteStringTag: 2142 case kSeqStringTag | kTwoByteStringTag:
2092 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); 2143 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2093 case kConsStringTag | kAsciiStringTag: 2144 case kConsStringTag | kAsciiStringTag:
2094 case kConsStringTag | kTwoByteStringTag: 2145 case kConsStringTag | kTwoByteStringTag:
2095 return ConsString::cast(this)->ConsStringGet(index); 2146 return ConsString::cast(this)->ConsStringGet(index);
2096 case kExternalStringTag | kAsciiStringTag: 2147 case kExternalStringTag | kAsciiStringTag:
2097 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index); 2148 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2098 case kExternalStringTag | kTwoByteStringTag: 2149 case kExternalStringTag | kTwoByteStringTag:
2099 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); 2150 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
2151 case kSlicedStringTag | kAsciiStringTag:
2152 case kSlicedStringTag | kTwoByteStringTag:
2153 return SlicedString::cast(this)->SlicedStringGet(index);
2100 default: 2154 default:
2101 break; 2155 break;
2102 } 2156 }
2103 2157
2104 UNREACHABLE(); 2158 UNREACHABLE();
2105 return 0; 2159 return 0;
2106 } 2160 }
2107 2161
2108 2162
2109 void String::Set(int index, uint16_t value) { 2163 void String::Set(int index, uint16_t value) {
2110 ASSERT(index >= 0 && index < length()); 2164 ASSERT(index >= 0 && index < length());
2111 ASSERT(StringShape(this).IsSequential()); 2165 ASSERT(StringShape(this).IsSequential());
2112 2166
2113 return this->IsAsciiRepresentation() 2167 return this->IsAsciiRepresentation()
2114 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value) 2168 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2115 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value); 2169 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
2116 } 2170 }
2117 2171
2118 2172
2119 bool String::IsFlat() { 2173 bool String::IsFlat() {
2120 switch (StringShape(this).representation_tag()) { 2174 if (!StringShape(this).IsCons()) return true;
2121 case kConsStringTag: { 2175 return ConsString::cast(this)->second()->length() == 0;
2122 String* second = ConsString::cast(this)->second();
2123 // Only flattened strings have second part empty.
2124 return second->length() == 0;
2125 }
2126 default:
2127 return true;
2128 }
2129 } 2176 }
2130 2177
2131 2178
2179 String* String::GetUnderlying() {
2180 // Giving direct access to underlying string only makes sense if the
2181 // wrapping string is already flattened.
2182 ASSERT(this->IsFlat());
2183 ASSERT(StringShape(this).IsIndirect());
2184 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2185 const int kUnderlyingOffset = SlicedString::kParentOffset;
2186 return String::cast(READ_FIELD(this, kUnderlyingOffset));
2187 }
2188
2189
2132 uint16_t SeqAsciiString::SeqAsciiStringGet(int index) { 2190 uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
2133 ASSERT(index >= 0 && index < length()); 2191 ASSERT(index >= 0 && index < length());
2134 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); 2192 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2135 } 2193 }
2136 2194
2137 2195
2138 void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) { 2196 void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
2139 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode); 2197 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2140 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, 2198 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2141 static_cast<byte>(value)); 2199 static_cast<byte>(value));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2177 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) { 2235 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
2178 return SizeFor(length()); 2236 return SizeFor(length());
2179 } 2237 }
2180 2238
2181 2239
2182 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) { 2240 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
2183 return SizeFor(length()); 2241 return SizeFor(length());
2184 } 2242 }
2185 2243
2186 2244
2245 String* SlicedString::parent() {
2246 return String::cast(READ_FIELD(this, kParentOffset));
2247 }
2248
2249
2250 void SlicedString::set_parent(String* parent) {
2251 ASSERT(parent->IsSeqString());
2252 WRITE_FIELD(this, kParentOffset, parent);
2253 }
2254
2255
2256 SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2257
2258
2187 String* ConsString::first() { 2259 String* ConsString::first() {
2188 return String::cast(READ_FIELD(this, kFirstOffset)); 2260 return String::cast(READ_FIELD(this, kFirstOffset));
2189 } 2261 }
2190 2262
2191 2263
2192 Object* ConsString::unchecked_first() { 2264 Object* ConsString::unchecked_first() {
2193 return READ_FIELD(this, kFirstOffset); 2265 return READ_FIELD(this, kFirstOffset);
2194 } 2266 }
2195 2267
2196 2268
(...skipping 2298 matching lines...) Expand 10 before | Expand all | Expand 10 after
4495 #undef WRITE_INT_FIELD 4567 #undef WRITE_INT_FIELD
4496 #undef READ_SHORT_FIELD 4568 #undef READ_SHORT_FIELD
4497 #undef WRITE_SHORT_FIELD 4569 #undef WRITE_SHORT_FIELD
4498 #undef READ_BYTE_FIELD 4570 #undef READ_BYTE_FIELD
4499 #undef WRITE_BYTE_FIELD 4571 #undef WRITE_BYTE_FIELD
4500 4572
4501 4573
4502 } } // namespace v8::internal 4574 } } // namespace v8::internal
4503 4575
4504 #endif // V8_OBJECTS_INL_H_ 4576 #endif // V8_OBJECTS_INL_H_
OLDNEW
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-visiting.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698