51 // Interface to java.lang.String objects |
51 // Interface to java.lang.String objects |
52 |
52 |
53 class java_lang_String : AllStatic { |
53 class java_lang_String : AllStatic { |
54 private: |
54 private: |
55 static int value_offset; |
55 static int value_offset; |
56 static int offset_offset; |
|
57 static int count_offset; |
|
58 static int hash_offset; |
56 static int hash_offset; |
|
57 static int coder_offset; |
59 |
58 |
60 static bool initialized; |
59 static bool initialized; |
61 |
60 |
62 static Handle basic_create(int length, TRAPS); |
61 static Handle basic_create(int length, bool byte_arr, TRAPS); |
63 |
62 |
64 static void set_offset(oop string, int offset) { |
63 static void set_coder(oop string, jbyte coder) { |
65 assert(initialized, "Must be initialized"); |
64 assert(initialized, "Must be initialized"); |
66 if (offset_offset > 0) { |
65 if (coder_offset > 0) { |
67 string->int_field_put(offset_offset, offset); |
66 string->byte_field_put(coder_offset, coder); |
68 } |
67 } |
69 } |
68 } |
70 static void set_count( oop string, int count) { |
69 |
71 assert(initialized, "Must be initialized"); |
70 public: |
72 if (count_offset > 0) { |
71 |
73 string->int_field_put(count_offset, count); |
72 // Coders |
74 } |
73 enum Coder { |
75 } |
74 CODER_LATIN1 = 0, |
76 |
75 CODER_UTF16 = 1 |
77 public: |
76 }; |
|
77 |
78 static void compute_offsets(); |
78 static void compute_offsets(); |
79 |
79 |
80 // Instance creation |
80 // Instance creation |
81 static Handle create_from_unicode(jchar* unicode, int len, TRAPS); |
81 static Handle create_from_unicode(jchar* unicode, int len, TRAPS); |
82 static oop create_oop_from_unicode(jchar* unicode, int len, TRAPS); |
82 static oop create_oop_from_unicode(jchar* unicode, int len, TRAPS); |
84 static oop create_oop_from_str(const char* utf8_str, TRAPS); |
84 static oop create_oop_from_str(const char* utf8_str, TRAPS); |
85 static Handle create_from_symbol(Symbol* symbol, TRAPS); |
85 static Handle create_from_symbol(Symbol* symbol, TRAPS); |
86 static Handle create_from_platform_dependent_str(const char* str, TRAPS); |
86 static Handle create_from_platform_dependent_str(const char* str, TRAPS); |
87 static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS); |
87 static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS); |
88 |
88 |
89 static bool has_offset_field() { |
|
90 assert(initialized, "Must be initialized"); |
|
91 return (offset_offset > 0); |
|
92 } |
|
93 |
|
94 static bool has_count_field() { |
|
95 assert(initialized, "Must be initialized"); |
|
96 return (count_offset > 0); |
|
97 } |
|
98 |
|
99 static bool has_hash_field() { |
89 static bool has_hash_field() { |
100 assert(initialized, "Must be initialized"); |
90 assert(initialized, "Must be initialized"); |
101 return (hash_offset > 0); |
91 return (hash_offset > 0); |
102 } |
92 } |
|
93 static bool has_coder_field() { |
|
94 assert(initialized, "Must be initialized"); |
|
95 return (coder_offset > 0); |
|
96 } |
|
97 |
|
98 static void set_compact_strings(bool value); |
103 |
99 |
104 static int value_offset_in_bytes() { |
100 static int value_offset_in_bytes() { |
105 assert(initialized && (value_offset > 0), "Must be initialized"); |
101 assert(initialized && (value_offset > 0), "Must be initialized"); |
106 return value_offset; |
102 return value_offset; |
107 } |
103 } |
108 static int count_offset_in_bytes() { |
|
109 assert(initialized && (count_offset > 0), "Must be initialized"); |
|
110 return count_offset; |
|
111 } |
|
112 static int offset_offset_in_bytes() { |
|
113 assert(initialized && (offset_offset > 0), "Must be initialized"); |
|
114 return offset_offset; |
|
115 } |
|
116 static int hash_offset_in_bytes() { |
104 static int hash_offset_in_bytes() { |
117 assert(initialized && (hash_offset > 0), "Must be initialized"); |
105 assert(initialized && (hash_offset > 0), "Must be initialized"); |
118 return hash_offset; |
106 return hash_offset; |
|
107 } |
|
108 static int coder_offset_in_bytes() { |
|
109 assert(initialized && (coder_offset > 0), "Must be initialized"); |
|
110 return coder_offset; |
119 } |
111 } |
120 |
112 |
121 static void set_value_raw(oop string, typeArrayOop buffer) { |
113 static void set_value_raw(oop string, typeArrayOop buffer) { |
122 assert(initialized, "Must be initialized"); |
114 assert(initialized, "Must be initialized"); |
123 string->obj_field_put_raw(value_offset, buffer); |
115 string->obj_field_put_raw(value_offset, buffer); |
140 static unsigned int hash(oop java_string) { |
132 static unsigned int hash(oop java_string) { |
141 assert(initialized && (hash_offset > 0), "Must be initialized"); |
133 assert(initialized && (hash_offset > 0), "Must be initialized"); |
142 assert(is_instance(java_string), "must be java_string"); |
134 assert(is_instance(java_string), "must be java_string"); |
143 return java_string->int_field(hash_offset); |
135 return java_string->int_field(hash_offset); |
144 } |
136 } |
145 static int offset(oop java_string) { |
137 static bool is_latin1(oop java_string) { |
146 assert(initialized, "Must be initialized"); |
138 assert(initialized, "Must be initialized"); |
147 assert(is_instance(java_string), "must be java_string"); |
139 assert(is_instance(java_string), "must be java_string"); |
148 if (offset_offset > 0) { |
140 if (coder_offset > 0) { |
149 return java_string->int_field(offset_offset); |
141 jbyte coder = java_string->byte_field(coder_offset); |
|
142 assert(CompactStrings || coder == CODER_UTF16, "Must be UTF16 without CompactStrings"); |
|
143 return coder == CODER_LATIN1; |
150 } else { |
144 } else { |
151 return 0; |
145 return false; |
152 } |
146 } |
153 } |
147 } |
154 static int length(oop java_string) { |
148 static int length(oop java_string) { |
155 assert(initialized, "Must be initialized"); |
149 assert(initialized, "Must be initialized"); |
156 assert(is_instance(java_string), "must be java_string"); |
150 assert(is_instance(java_string), "must be java_string"); |
157 if (count_offset > 0) { |
151 typeArrayOop value_array = ((typeArrayOop)java_string->obj_field(value_offset)); |
158 return java_string->int_field(count_offset); |
152 if (value_array == NULL) { |
159 } else { |
153 return 0; |
160 typeArrayOop value_array = ((typeArrayOop)java_string->obj_field(value_offset)); |
|
161 if (value_array == NULL) { |
|
162 return 0; |
|
163 } else { |
|
164 return value_array->length(); |
|
165 } |
|
166 } |
154 } |
|
155 int arr_length = value_array->length(); |
|
156 if (!is_latin1(java_string)) { |
|
157 assert((arr_length & 1) == 0, "should be even for UTF16 string"); |
|
158 arr_length >>= 1; // convert number of bytes to number of elements |
|
159 } |
|
160 return arr_length; |
167 } |
161 } |
168 static int utf8_length(oop java_string); |
162 static int utf8_length(oop java_string); |
169 |
163 |
170 // String converters |
164 // String converters |
171 static char* as_utf8_string(oop java_string); |
165 static char* as_utf8_string(oop java_string); |
185 // in the String.hashCode method(), but is precomputed for String |
179 // in the String.hashCode method(), but is precomputed for String |
186 // objects in the shared archive file. |
180 // objects in the shared archive file. |
187 // hash P(31) from Kernighan & Ritchie |
181 // hash P(31) from Kernighan & Ritchie |
188 // |
182 // |
189 // For this reason, THIS ALGORITHM MUST MATCH String.hashCode(). |
183 // For this reason, THIS ALGORITHM MUST MATCH String.hashCode(). |
190 template <typename T> static unsigned int hash_code(T* s, int len) { |
184 static unsigned int hash_code(const jchar* s, int len) { |
191 unsigned int h = 0; |
185 unsigned int h = 0; |
192 while (len-- > 0) { |
186 while (len-- > 0) { |
193 h = 31*h + (unsigned int) *s; |
187 h = 31*h + (unsigned int) *s; |
194 s++; |
188 s++; |
195 } |
189 } |
196 return h; |
190 return h; |
197 } |
191 } |
|
192 |
|
193 static unsigned int hash_code(const jbyte* s, int len) { |
|
194 unsigned int h = 0; |
|
195 while (len-- > 0) { |
|
196 h = 31*h + (((unsigned int) *s) & 0xFF); |
|
197 s++; |
|
198 } |
|
199 return h; |
|
200 } |
|
201 |
198 static unsigned int hash_code(oop java_string); |
202 static unsigned int hash_code(oop java_string); |
|
203 static unsigned int latin1_hash_code(typeArrayOop value, int len); |
199 |
204 |
200 // This is the string hash code used by the StringTable, which may be |
205 // This is the string hash code used by the StringTable, which may be |
201 // the same as String.hashCode or an alternate hash code. |
206 // the same as String.hashCode or an alternate hash code. |
202 static unsigned int hash_string(oop java_string); |
207 static unsigned int hash_string(oop java_string); |
203 |
208 |
449 |
454 |
450 public: |
455 public: |
451 // parent ThreadGroup |
456 // parent ThreadGroup |
452 static oop parent(oop java_thread_group); |
457 static oop parent(oop java_thread_group); |
453 // name |
458 // name |
454 static typeArrayOop name(oop java_thread_group); |
459 static const char* name(oop java_thread_group); |
455 // ("name as oop" accessor is not necessary) |
460 // ("name as oop" accessor is not necessary) |
456 // Number of threads in group |
461 // Number of threads in group |
457 static int nthreads(oop java_thread_group); |
462 static int nthreads(oop java_thread_group); |
458 // threads |
463 // threads |
459 static objArrayOop threads(oop java_thread_group); |
464 static objArrayOop threads(oop java_thread_group); |