Changeset 54843 in webkit for trunk/JavaScriptCore/runtime/JSString.h
- Timestamp:
- Feb 16, 2010, 4:01:58 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/JSString.h
r54804 r54843 33 33 namespace JSC { 34 34 35 // FIXME: this class is on its way out into a different header.36 class Rope : public RefCounted<Rope> {37 public:38 // A Rope is composed from a set of smaller strings called Fibers.39 // Each Fiber in a rope is either UString::Rep or another Rope.40 class Fiber {41 public:42 Fiber() : m_value(0) {}43 Fiber(UString::Rep* string) : m_value(reinterpret_cast<intptr_t>(string)) {}44 Fiber(Rope* rope) : m_value(reinterpret_cast<intptr_t>(rope) | 1) {}45 46 Fiber(void* nonFiber) : m_value(reinterpret_cast<intptr_t>(nonFiber)) {}47 48 void deref()49 {50 if (isRope())51 rope()->deref();52 else53 string()->deref();54 }55 56 Fiber& ref()57 {58 if (isString())59 string()->ref();60 else61 rope()->ref();62 return *this;63 }64 65 unsigned refAndGetLength()66 {67 if (isString()) {68 UString::Rep* rep = string();69 return rep->ref()->size();70 } else {71 Rope* r = rope();72 r->ref();73 return r->length();74 }75 }76 77 bool isRope() { return m_value & 1; }78 Rope* rope() { return reinterpret_cast<Rope*>(m_value & ~1); }79 bool isString() { return !isRope(); }80 UString::Rep* string() { return reinterpret_cast<UString::Rep*>(m_value); }81 82 void* nonFiber() { return reinterpret_cast<void*>(m_value); }83 private:84 intptr_t m_value;85 };86 87 // Creates a Rope comprising of 'fiberCount' Fibers.88 // The Rope is constructed in an uninitialized state - initialize must be called for each Fiber in the Rope.89 static PassRefPtr<Rope> tryCreateUninitialized(unsigned fiberCount)90 {91 void* allocation;92 if (tryFastMalloc(sizeof(Rope) + (fiberCount - 1) * sizeof(Fiber)).getValue(allocation))93 return adoptRef(new (allocation) Rope(fiberCount));94 return 0;95 }96 97 ~Rope();98 void destructNonRecursive();99 100 void initializeFiber(unsigned &index, Fiber& fiber)101 {102 m_fibers[index++] = fiber;103 m_length += fiber.refAndGetLength();104 }105 void initializeFiber(unsigned &index, UStringImpl* impl)106 {107 m_fibers[index++] = Fiber(impl);108 m_length += impl->ref()->size();109 }110 111 unsigned fiberCount() { return m_fiberCount; }112 unsigned length() { return m_length; }113 Fiber& fibers(unsigned index) { return m_fibers[index]; }114 115 private:116 Rope(unsigned fiberCount) : m_fiberCount(fiberCount), m_length(0) {}117 void* operator new(size_t, void* inPlace) { return inPlace; }118 119 unsigned m_fiberCount;120 unsigned m_length;121 Fiber m_fibers[1];122 };123 124 35 class JSString; 125 36 … … 156 67 friend class JIT; 157 68 friend class JSGlobalData; 69 70 typedef URopeImpl Rope; 158 71 159 72 class RopeBuilder { … … 181 94 if (jsString->isRope()) { 182 95 for (unsigned i = 0; i < jsString->m_fiberCount; ++i) 183 append(jsString->m_ fibers[i]);96 append(jsString->m_other.m_fibers[i]); 184 97 } else 185 98 append(jsString->string()); … … 216 129 JSString(JSGlobalData* globalData, PassRefPtr<UString::Rep> value, HasOtherOwnerType) 217 130 : JSCell(globalData->stringStructure.get()) 218 , m_length(value-> size())131 , m_length(value->length()) 219 132 , m_value(value) 220 133 , m_fiberCount(0) … … 226 139 , m_fiberCount(1) 227 140 { 228 m_ fibers[0] = rope.releaseRef();141 m_other.m_fibers[0] = rope.releaseRef(); 229 142 } 230 143 // This constructor constructs a new string by concatenating s1 & s2. … … 290 203 { 291 204 // nasty hack because we can't union non-POD types 292 m_ fibers[0] = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(finalizer));293 m_ fibers[1]= context;205 m_other.m_finalizerCallback = finalizer; 206 m_other.m_finalizerContext = context; 294 207 Heap::heap(this)->reportExtraMemoryCost(value.cost()); 295 208 } … … 299 212 ASSERT(vptr() == JSGlobalData::jsStringVPtr); 300 213 for (unsigned i = 0; i < m_fiberCount; ++i) 301 m_fibers[i].deref(); 302 303 if (!m_fiberCount && m_fibers[0].nonFiber()) { 304 JSStringFinalizerCallback finalizer = reinterpret_cast<JSStringFinalizerCallback>(m_fibers[0].nonFiber()); 305 finalizer(this, m_fibers[1].nonFiber()); 306 } 214 m_other.m_fibers[i]->deref(); 215 216 if (!m_fiberCount && m_other.m_finalizerCallback) 217 m_other.m_finalizerCallback(this, m_other.m_finalizerContext); 307 218 } 308 219 … … 343 254 void appendStringInConstruct(unsigned& index, const UString& string) 344 255 { 345 m_fibers[index++] = Rope::Fiber(string.rep()->ref()); 256 UStringImpl* impl = string.rep(); 257 impl->ref(); 258 m_other.m_fibers[index++] = impl; 346 259 } 347 260 … … 349 262 { 350 263 if (jsString->isRope()) { 351 for (unsigned i = 0; i < jsString->m_fiberCount; ++i) 352 m_fibers[index++] = jsString->m_fibers[i].ref(); 264 for (unsigned i = 0; i < jsString->m_fiberCount; ++i) { 265 Rope::Fiber fiber = jsString->m_other.m_fibers[i]; 266 fiber->ref(); 267 m_other.m_fibers[index++] = fiber; 268 } 353 269 } else 354 270 appendStringInConstruct(index, jsString->string()); … … 365 281 } else { 366 282 UString u(v.toString(exec)); 367 m_fibers[index++] = Rope::Fiber(u.rep()->ref()); 283 UStringImpl* impl = u.rep(); 284 impl->ref(); 285 m_other.m_fibers[index++] = impl; 368 286 m_length += u.size(); 369 287 } … … 392 310 mutable UString m_value; 393 311 mutable unsigned m_fiberCount; 394 mutable Rope::Fiber m_fibers[s_maxInternalRopeLength]; 312 // This structure exists to support a temporary workaround for a GC issue. 313 struct JSStringFinalizerStruct { 314 JSStringFinalizerStruct() : m_finalizerCallback(0) {} 315 union { 316 mutable Rope::Fiber m_fibers[s_maxInternalRopeLength]; 317 struct { 318 JSStringFinalizerCallback m_finalizerCallback; 319 void* m_finalizerContext; 320 }; 321 }; 322 } m_other; 395 323 396 324 bool isRope() const { return m_fiberCount; }
Note:
See TracChangeset
for help on using the changeset viewer.