/[jscoverage]/trunk/js/jsatom.cpp
ViewVC logotype

Diff of /trunk/js/jsatom.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 460 by siliconforks, Sat Sep 26 23:15:22 2009 UTC revision 507 by siliconforks, Sun Jan 10 07:23:34 2010 UTC
# Line 1  Line 1 
1  /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-  /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2   *   *
3   * ***** BEGIN LICENSE BLOCK *****   * ***** BEGIN LICENSE BLOCK *****
4   * Version: MPL 1.1/GPL 2.0/LGPL 2.1   * Version: MPL 1.1/GPL 2.0/LGPL 2.1
# Line 40  Line 40 
40  /*  /*
41   * JS atom table.   * JS atom table.
42   */   */
 #include "jsstddef.h"  
43  #include <stdlib.h>  #include <stdlib.h>
44  #include <string.h>  #include <string.h>
45  #include "jstypes.h"  #include "jstypes.h"
46    #include "jsstdint.h"
47  #include "jsutil.h" /* Added by JSIFY */  #include "jsutil.h" /* Added by JSIFY */
48  #include "jshash.h" /* Added by JSIFY */  #include "jshash.h" /* Added by JSIFY */
49  #include "jsprf.h"  #include "jsprf.h"
# Line 58  Line 58 
58  #include "jsscan.h"  #include "jsscan.h"
59  #include "jsstr.h"  #include "jsstr.h"
60  #include "jsversion.h"  #include "jsversion.h"
61    #include "jsstrinlines.h"
62    
63  /*  /*
64   * ATOM_HASH assumes that JSHashNumber is 32-bit even on 64-bit systems.   * ATOM_HASH assumes that JSHashNumber is 32-bit even on 64-bit systems.
# Line 98  Line 99 
99   * The elements of the array after the first empty string define strings   * The elements of the array after the first empty string define strings
100   * corresponding to the two boolean literals, false and true, followed by the   * corresponding to the two boolean literals, false and true, followed by the
101   * JSType enumerators from jspubtd.h starting with "undefined" for JSTYPE_VOID   * JSType enumerators from jspubtd.h starting with "undefined" for JSTYPE_VOID
102   * (which is pseudo-boolean 2) and continuing as initialized below. The static   * (which is special-value 2) and continuing as initialized below. The static
103   * asserts check these relations.   * asserts check these relations.
104   */   */
105  JS_STATIC_ASSERT(JSTYPE_LIMIT == 8);  JS_STATIC_ASSERT(JSTYPE_LIMIT == 8);
# Line 325  Line 326 
326  static JSDHashNumber  static JSDHashNumber
327  HashDouble(JSDHashTable *table, const void *key)  HashDouble(JSDHashTable *table, const void *key)
328  {  {
     jsdouble d;  
   
329      JS_ASSERT(IS_DOUBLE_TABLE(table));      JS_ASSERT(IS_DOUBLE_TABLE(table));
330      d = *(jsdouble *)key;      return JS_HASH_DOUBLE(*(jsdouble *)key);
     return JSDOUBLE_HI32(d) ^ JSDOUBLE_LO32(d);  
331  }  }
332    
333  static JSDHashNumber  static JSDHashNumber
# Line 559  Line 557 
557  void  void
558  js_TraceAtomState(JSTracer *trc, JSBool allAtoms)  js_TraceAtomState(JSTracer *trc, JSBool allAtoms)
559  {  {
560      JSAtomState *state;      JSRuntime *rt = trc->context->runtime;
561        JSAtomState *state = &rt->atomState;
562    
     state = &trc->context->runtime->atomState;  
563      if (allAtoms) {      if (allAtoms) {
564          JS_DHashTableEnumerate(&state->doubleAtoms, js_locked_atom_tracer, trc);          JS_DHashTableEnumerate(&state->doubleAtoms, js_locked_atom_tracer, trc);
565          JS_DHashTableEnumerate(&state->stringAtoms, js_locked_atom_tracer, trc);          JS_DHashTableEnumerate(&state->stringAtoms, js_locked_atom_tracer, trc);
# Line 673  Line 671 
671      JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_TMPSTR|ATOM_NOCOPY)));      JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_TMPSTR|ATOM_NOCOPY)));
672      JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR);      JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR);
673    
674        if (str->isAtomized())
675            return (JSAtom *) STRING_TO_JSVAL(str);
676    
677        size_t length = str->length();
678        if (length == 1) {
679            jschar c = str->chars()[0];
680            if (c < UNIT_STRING_LIMIT)
681                return (JSAtom *) STRING_TO_JSVAL(JSString::unitString(c));
682        }
683    
684        /*
685         * Here we know that JSString::intStringTable covers only 256 (or at least
686         * not 1000 or more) chars. We rely on order here to resolve the unit vs.
687         * int string atom identity issue by giving priority to unit strings for
688         * '0' through '9' (see JSString::intString in jsstrinlines.h).
689         */
690        JS_STATIC_ASSERT(INT_STRING_LIMIT <= 999);
691        if (2 <= length && length <= 3) {
692            const jschar *chars = str->chars();
693    
694            if ('1' <= chars[0] && chars[0] <= '9' &&
695                '0' <= chars[1] && chars[1] <= '9' &&
696                (length == 2 || ('0' <= chars[2] && chars[2] <= '9'))) {
697                jsint i = (chars[0] - '0') * 10 + chars[1] - '0';
698    
699                if (length == 3)
700                    i = i * 10 + chars[2] - '0';
701                if (jsuint(i) < INT_STRING_LIMIT)
702                    return (JSAtom *) STRING_TO_JSVAL(JSString::intString(i));
703            }
704        }
705    
706      state = &cx->runtime->atomState;      state = &cx->runtime->atomState;
707      table = &state->stringAtoms;      table = &state->stringAtoms;
708    
# Line 690  Line 720 
720           * trigger GC which may rehash the table and make the entry invalid.           * trigger GC which may rehash the table and make the entry invalid.
721           */           */
722          ++table->generation;          ++table->generation;
723          if (!(flags & ATOM_TMPSTR) && JSSTRING_IS_FLAT(str)) {          if (!(flags & ATOM_TMPSTR) && str->isFlat()) {
724              JSFLATSTR_CLEAR_MUTABLE(str);              str->flatClearMutable();
725              key = str;              key = str;
726          } else {          } else {
727              gen = table->generation;              gen = table->generation;
# Line 699  Line 729 
729    
730              if (flags & ATOM_TMPSTR) {              if (flags & ATOM_TMPSTR) {
731                  if (flags & ATOM_NOCOPY) {                  if (flags & ATOM_NOCOPY) {
732                      key = js_NewString(cx, JSFLATSTR_CHARS(str),                      key = js_NewString(cx, str->flatChars(), str->flatLength());
                                        JSFLATSTR_LENGTH(str));  
733                      if (!key)                      if (!key)
734                          return NULL;                          return NULL;
735    
736                      /* Finish handing off chars to the GC'ed key string. */                      /* Finish handing off chars to the GC'ed key string. */
737                      str->u.chars = NULL;                      str->mChars = NULL;
738                  } else {                  } else {
739                      key = js_NewStringCopyN(cx, JSFLATSTR_CHARS(str),                      key = js_NewStringCopyN(cx, str->flatChars(), str->flatLength());
                                             JSFLATSTR_LENGTH(str));  
740                      if (!key)                      if (!key)
741                          return NULL;                          return NULL;
742                  }                  }
743             } else {             } else {
744                  JS_ASSERT(JSSTRING_IS_DEPENDENT(str));                  JS_ASSERT(str->isDependent());
745                  if (!js_UndependString(cx, str))                  if (!js_UndependString(cx, str))
746                      return NULL;                      return NULL;
747                  key = str;                  key = str;
# Line 735  Line 763 
763              }              }
764          }          }
765          INIT_ATOM_ENTRY(entry, key);          INIT_ATOM_ENTRY(entry, key);
766          JSFLATSTR_SET_ATOMIZED(key);          key->flatSetAtomized();
767      }      }
768    
769    finish:    finish:
770      ADD_ATOM_ENTRY_FLAGS(entry, flags & (ATOM_PINNED | ATOM_INTERNED));      ADD_ATOM_ENTRY_FLAGS(entry, flags & (ATOM_PINNED | ATOM_INTERNED));
771      JS_ASSERT(JSSTRING_IS_ATOMIZED(key));      JS_ASSERT(key->isAtomized());
772      v = STRING_TO_JSVAL(key);      v = STRING_TO_JSVAL(key);
773      cx->weakRoots.lastAtom = v;      cx->weakRoots.lastAtom = v;
774      JS_UNLOCK(cx, &state->lock);      JS_UNLOCK(cx, &state->lock);
# Line 782  Line 810 
810          flags |= ATOM_NOCOPY;          flags |= ATOM_NOCOPY;
811      }      }
812    
813      JSFLATSTR_INIT(&str, (jschar *)chars, inflatedLength);      str.initFlat(chars, inflatedLength);
814      atom = js_AtomizeString(cx, &str, ATOM_TMPSTR | flags);      atom = js_AtomizeString(cx, &str, ATOM_TMPSTR | flags);
815      if (chars != inflated && str.u.chars)      if (chars != inflated && str.flatChars())
816          JS_free(cx, chars);          cx->free(chars);
817      return atom;      return atom;
818  }  }
819    
# Line 794  Line 822 
822  {  {
823      JSString str;      JSString str;
824    
825      JSFLATSTR_INIT(&str, (jschar *)chars, length);      str.initFlat((jschar *)chars, length);
826      return js_AtomizeString(cx, &str, ATOM_TMPSTR | flags);      return js_AtomizeString(cx, &str, ATOM_TMPSTR | flags);
827  }  }
828    
# Line 805  Line 833 
833      JSAtomState *state;      JSAtomState *state;
834      JSDHashEntryHdr *hdr;      JSDHashEntryHdr *hdr;
835    
836      JSFLATSTR_INIT(&str, (jschar *)chars, length);      if (length == 1) {
837            jschar c = *chars;
838            if (c < UNIT_STRING_LIMIT)
839                return (JSAtom *) STRING_TO_JSVAL(JSString::unitString(c));
840        }
841    
842        str.initFlat((jschar *)chars, length);
843      state = &cx->runtime->atomState;      state = &cx->runtime->atomState;
844    
845      JS_LOCK(cx, &state->lock);      JS_LOCK(cx, &state->lock);
# Line 840  Line 874 
874      return JS_TRUE;      return JS_TRUE;
875  }  }
876    
 JSBool  
 js_ValueToStringId(JSContext *cx, jsval v, jsid *idp)  
 {  
     JSString *str;  
     JSAtom *atom;  
   
     /*  
      * Optimize for the common case where v is an already-atomized string. The  
      * comment in jsstr.h before the JSSTRING_SET_ATOMIZED macro's definition  
      * explains why this is thread-safe. The extra rooting via lastAtom (which  
      * would otherwise be done in js_js_AtomizeString) ensures the caller that  
      * the resulting id at is least weakly rooted.  
      */  
     if (JSVAL_IS_STRING(v)) {  
         str = JSVAL_TO_STRING(v);  
         if (JSSTRING_IS_ATOMIZED(str)) {  
             cx->weakRoots.lastAtom = v;  
             *idp = ATOM_TO_JSID((JSAtom *) v);  
             return JS_TRUE;  
         }  
     } else {  
         str = js_ValueToString(cx, v);  
         if (!str)  
             return JS_FALSE;  
     }  
     atom = js_AtomizeString(cx, str, 0);  
     if (!atom)  
         return JS_FALSE;  
     *idp = ATOM_TO_JSID(atom);  
     return JS_TRUE;  
 }  
   
877  #ifdef DEBUG  #ifdef DEBUG
878    
879  static JSDHashOperator  static JSDHashOperator
# Line 1128  Line 1130 
1130               * with the given key.               * with the given key.
1131               */               */
1132              if (how == HOIST && ale->entry.next) {              if (how == HOIST && ale->entry.next) {
1133                    JS_ASSERT(*hep == &ale->entry);
1134                  *hep = ale->entry.next;                  *hep = ale->entry.next;
1135                  ale->entry.next = NULL;                  ale->entry.next = NULL;
1136                  do {                  do {

Legend:
Removed from v.460  
changed lines
  Added in v.507

  ViewVC Help
Powered by ViewVC 1.1.24