Changeset 51964 in webkit for trunk/JavaScriptCore/runtime/JSString.h
- Timestamp:
- Dec 10, 2009, 2:13:15 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/JSString.h
r51933 r51964 76 76 Fiber(Rope* rope) : m_value(reinterpret_cast<intptr_t>(rope) | 1) {} 77 77 78 void deref() 79 { 80 if (isRope()) 81 rope()->deref(); 82 else 83 string()->deref(); 84 } 85 86 Fiber& ref() 87 { 88 if (isString()) 89 string()->ref(); 90 else 91 rope()->ref(); 92 return *this; 93 } 94 95 unsigned refAndGetLength() 96 { 97 if (isString()) { 98 UString::Rep* rep = string(); 99 return rep->ref()->len; 100 } else { 101 Rope* r = rope(); 102 r->ref(); 103 return r->stringLength(); 104 } 105 } 106 78 107 bool isRope() { return m_value & 1; } 79 108 Rope* rope() { return reinterpret_cast<Rope*>(m_value & ~1); } … … 98 127 void destructNonRecursive(); 99 128 100 void initializeFiber(unsigned index, const UString& string) 129 void append(unsigned &index, Fiber& fiber) 130 { 131 m_fibers[index++] = fiber; 132 m_stringLength += fiber.refAndGetLength(); 133 } 134 void append(unsigned &index, const UString& string) 101 135 { 102 136 UString::Rep* rep = string.rep(); 103 rep->ref(); 104 m_fibers[index] = Fiber(rep); 105 m_stringLength += rep->len; 137 m_fibers[index++] = Fiber(rep); 138 m_stringLength += rep->ref()->len; 106 139 } 107 void initializeFiber(unsigned index, Rope* rope)140 void append(unsigned& index, JSString* jsString) 108 141 { 109 rope->ref(); 110 m_fibers[index] = Fiber(rope); 111 m_stringLength += rope->stringLength(); 112 } 113 void initializeFiber(unsigned index, JSString* jsString) 114 { 115 if (jsString->isRope()) 116 initializeFiber(index, jsString->rope()); 117 else 118 initializeFiber(index, jsString->string()); 142 if (jsString->isRope()) { 143 for (unsigned i = 0; i < jsString->m_ropeLength; ++i) 144 append(index, jsString->m_fibers[i]); 145 } else 146 append(index, jsString->string()); 119 147 } 120 148 … … 134 162 JSString(JSGlobalData* globalData, const UString& value) 135 163 : JSCell(globalData->stringStructure.get()) 136 , m_ length(value.size())164 , m_stringLength(value.size()) 137 165 , m_value(value) 166 , m_ropeLength(0) 138 167 { 139 168 Heap::heap(this)->reportExtraMemoryCost(value.cost()); … … 143 172 JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType) 144 173 : JSCell(globalData->stringStructure.get()) 145 , m_ length(value.size())174 , m_stringLength(value.size()) 146 175 , m_value(value) 176 , m_ropeLength(0) 147 177 { 148 178 } 149 179 JSString(JSGlobalData* globalData, PassRefPtr<UString::Rep> value, HasOtherOwnerType) 150 180 : JSCell(globalData->stringStructure.get()) 151 , m_ length(value->size())181 , m_stringLength(value->size()) 152 182 , m_value(value) 183 , m_ropeLength(0) 153 184 { 154 185 } 155 186 JSString(JSGlobalData* globalData, PassRefPtr<JSString::Rope> rope) 156 187 : JSCell(globalData->stringStructure.get()) 157 , m_length(rope->stringLength()) 158 , m_rope(rope) 159 { 188 , m_stringLength(rope->stringLength()) 189 , m_ropeLength(1) 190 { 191 m_fibers[0] = rope.releaseRef(); 192 } 193 // This constructor constructs a new string by concatenating s1 & s2. 194 // This should only be called with ropeLength <= 3. 195 JSString(JSGlobalData* globalData, unsigned ropeLength, JSString* s1, JSString* s2) 196 : JSCell(globalData->stringStructure.get()) 197 , m_stringLength(s1->length() + s2->length()) 198 , m_ropeLength(ropeLength) 199 { 200 ASSERT(ropeLength <= s_maxInternalRopeLength); 201 unsigned index = 0; 202 appendStringInConstruct(index, s1); 203 appendStringInConstruct(index, s2); 204 ASSERT(ropeLength == index); 205 } 206 // This constructor constructs a new string by concatenating v1, v2 & v3. 207 // This should only be called with ropeLength <= 3 ... which since every 208 // value must require a ropeLength of at least one implies that the length 209 // for each value must be exactly 1! 210 JSString(ExecState* exec, JSValue v1, JSValue v2, JSValue v3) 211 : JSCell(exec->globalData().stringStructure.get()) 212 , m_stringLength(0) 213 , m_ropeLength(s_maxInternalRopeLength) 214 { 215 unsigned index = 0; 216 appendValueInConstructAndIncrementLength(exec, index, v1); 217 appendValueInConstructAndIncrementLength(exec, index, v2); 218 appendValueInConstructAndIncrementLength(exec, index, v3); 219 ASSERT(index == s_maxInternalRopeLength); 220 } 221 222 ~JSString() 223 { 224 for (unsigned i = 0; i < m_ropeLength; ++i) 225 m_fibers[i].deref(); 160 226 } 161 227 162 228 const UString& value(ExecState* exec) const 163 229 { 164 if ( m_rope)230 if (isRope()) 165 231 resolveRope(exec); 166 232 return m_value; … … 168 234 const UString tryGetValue() const 169 235 { 170 if ( m_rope)236 if (isRope()) 171 237 UString(); 172 238 return m_value; 173 239 } 174 unsigned length() { return m_length; } 175 176 bool isRope() const { return m_rope; } 177 Rope* rope() { ASSERT(isRope()); return m_rope.get(); } 178 UString& string() { ASSERT(!isRope()); return m_value; } 240 unsigned length() { return m_stringLength; } 179 241 180 242 bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); … … 182 244 bool getStringPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&); 183 245 184 bool canGetIndex(unsigned i) { return i < m_ length; }246 bool canGetIndex(unsigned i) { return i < m_stringLength; } 185 247 JSString* getIndex(ExecState*, unsigned); 186 248 … … 191 253 JSString(VPtrStealingHackType) 192 254 : JSCell(0) 255 , m_ropeLength(0) 193 256 { 194 257 } 195 258 196 259 void resolveRope(ExecState*) const; 260 261 void appendStringInConstruct(unsigned& index, JSString* jsString) 262 { 263 if (jsString->isRope()) { 264 for (unsigned i = 0; i < jsString->m_ropeLength; ++i) 265 m_fibers[index++] = jsString->m_fibers[i].ref(); 266 } else 267 m_fibers[index++] = Rope::Fiber(jsString->string().rep()->ref()); 268 } 269 270 void appendValueInConstructAndIncrementLength(ExecState* exec, unsigned& index, JSValue v) 271 { 272 if (v.isString()) { 273 ASSERT(asCell(v)->isString()); 274 JSString* s = static_cast<JSString*>(asCell(v)); 275 ASSERT(s->ropeLength() == 1); 276 appendStringInConstruct(index, s); 277 m_stringLength += s->length(); 278 } else { 279 UString u(v.toString(exec)); 280 m_fibers[index++] = Rope::Fiber(u.rep()->ref()); 281 m_stringLength += u.size(); 282 } 283 } 197 284 198 285 virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; … … 212 299 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 213 300 301 static const unsigned s_maxInternalRopeLength = 3; 302 214 303 // A string is represented either by a UString or a Rope. 215 unsigned m_ length;304 unsigned m_stringLength; 216 305 mutable UString m_value; 217 mutable RefPtr<Rope> m_rope; 306 mutable unsigned m_ropeLength; 307 mutable Rope::Fiber m_fibers[s_maxInternalRopeLength]; 308 309 bool isRope() const { return m_ropeLength; } 310 UString& string() { ASSERT(!isRope()); return m_value; } 311 unsigned ropeLength() { return m_ropeLength ? m_ropeLength : 1; } 312 313 friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2); 314 friend JSValue jsString(ExecState* exec, Register* strings, unsigned count); 218 315 }; 219 316 … … 279 376 return new (globalData) JSString(globalData, s); 280 377 } 281 378 282 379 inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) 283 380 { … … 320 417 { 321 418 if (propertyName == exec->propertyNames().length) { 322 slot.setValue(jsNumber(exec, m_ length));419 slot.setValue(jsNumber(exec, m_stringLength)); 323 420 return true; 324 421 } … … 326 423 bool isStrictUInt32; 327 424 unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); 328 if (isStrictUInt32 && i < m_ length) {425 if (isStrictUInt32 && i < m_stringLength) { 329 426 slot.setValue(jsSingleCharacterSubstring(exec, value(exec), i)); 330 427 return true; … … 336 433 ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) 337 434 { 338 if (propertyName < m_ length) {435 if (propertyName < m_stringLength) { 339 436 slot.setValue(jsSingleCharacterSubstring(exec, value(exec), propertyName)); 340 437 return true;
Note:
See TracChangeset
for help on using the changeset viewer.