< prev index next >

src/hotspot/share/oops/symbol.cpp

Print this page

        

@@ -80,24 +80,115 @@
   _length_and_refcount =  pack_length_and_refcount(length(), PERM_REFCOUNT);
 }
 
 
 // ------------------------------------------------------------------
-// Symbol::starts_with
+// Symbol::contains_byte_at
 //
-// Tests if the symbol starts with the specified prefix of the given
-// length.
-bool Symbol::starts_with(const char* prefix, int len) const {
-  if (len > utf8_length()) return false;
+// Tests if the symbol contains the given byte at the given position.
+bool Symbol::contains_byte_at(int position, char code_byte) const {
+  if (position < 0)  return false;  // can happen with ends_with
+  if (position >= utf8_length()) return false;
+  return code_byte == char_at(position);
+}
+
+// ------------------------------------------------------------------
+// Symbol::contains_utf8_at
+//
+// Tests if the symbol contains the given utf8 substring
+// at the given byte position.
+bool Symbol::contains_utf8_at(int position, const char* substring, int len) const {
+  assert(len > 0 && substring != NULL && (int) strlen(substring) >= len,
+         "substring must be valid");
+  if (len == 1)  return contains_byte_at(position, substring[0]);
+  if (position < 0)  return false;  // can happen with ends_with
+  if (position + len > utf8_length()) return false;
   while (len-- > 0) {
-    if (prefix[len] != char_at(len))
+    if (substring[len] != char_at(position + len))
       return false;
   }
   assert(len == -1, "we should be at the beginning");
   return true;
 }
 
+bool Symbol::is_Q_signature() const {
+  return utf8_length() > 2 && char_at(0) == 'Q' && ends_with(';');
+}
+
+bool Symbol::is_Q_array_signature() const {
+  int l = utf8_length();
+  if (l < 2 || char_at(0) != '[' || char_at(l - 1) != ';') {
+    return false;
+  }
+  for (int i = 1; i < (l - 2); i++) {
+    char c = char_at(i);
+    if (c == 'Q') {
+      return true;
+    }
+    if (c != '[') {
+      return false;
+    }
+  }
+  return false;
+}
+
+bool Symbol::is_Q_method_signature() const {
+  assert(SignatureVerifier::is_valid_method_signature(this), "must be");
+  int len = utf8_length();
+  if (len > 4 && char_at(0) == '(') {
+    for (int i=1; i<len-3; i++) { // Must end with ")Qx;", where x is at least one character or more.
+      if (char_at(i) == ')' && char_at(i+1) == 'Q') {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool Symbol::is_Q_singledim_array_signature() const {
+  return utf8_length() > 3 && char_at(0) == '[' && char_at(1) == 'Q' && ends_with(';');
+}
+
+Symbol* Symbol::fundamental_name(TRAPS) {
+  if ((char_at(0) == 'Q' || char_at(0) == 'L') && ends_with(';')) {
+    return SymbolTable::new_symbol(this, 1, utf8_length() - 1);
+  } else {
+    // reference count is incremented to be consistent with the behavior with
+    // the SymbolTable::new_symbol() call above
+    this->increment_refcount();
+    return this;
+  }
+}
+
+bool Symbol::is_same_fundamental_type(Symbol* s) const {
+  if (this == s) return true;
+  if (utf8_length() < 3) return false;
+  int offset1, offset2, len;
+  if (ends_with(';')) {
+    if (char_at(0) != 'Q' && char_at(0) != 'L') return false;
+    offset1 = 1;
+    len = utf8_length() - 2;
+  } else {
+    offset1 = 0;
+    len = utf8_length();
+  }
+  if (ends_with(';')) {
+    if (s->char_at(0) != 'Q' && s->char_at(0) != 'L') return false;
+    offset2 = 1;
+  } else {
+    offset2 = 0;
+  }
+  if ((offset2 + len) > s->utf8_length()) return false;
+  if ((utf8_length() - offset1 * 2) != (s->utf8_length() - offset2 * 2))
+    return false;
+  int l = len;
+  while (l-- > 0) {
+    if (char_at(offset1 + l) != s->char_at(offset2 + l))
+      return false;
+  }
+  return true;
+}
 
 // ------------------------------------------------------------------
 // Symbol::index_of
 //
 // Finds if the given string is a substring of this symbol's utf8 bytes.

@@ -221,11 +312,11 @@
 static void print_array(outputStream *os, char *array_str, int len) {
   int dimensions = 0;
   for (int i = 0; i < len; ++i) {
     if (array_str[i] == '[') {
       dimensions++;
-    } else if (array_str[i] == 'L') {
+    } else if (array_str[i] == 'L' || array_str[i] == 'Q') {
       // Expected format: L<type name>;. Skip 'L' and ';' delimiting the type name.
       print_class(os, array_str+i+1, len-i-2);
       break;
     } else {
       os->print("%s", type2name(char2type(array_str[i])));

@@ -401,7 +492,19 @@
 
   jbyte* bytes = (jbyte*) s->bytes();
   return os::is_readable_range(bytes, bytes + len);
 }
 
+void Symbol::print_Qvalue_on(outputStream* st) const {
+  if (this == NULL) {
+    st->print("NULL");
+  } else {
+    st->print("'Q");
+    for (int i = 0; i < utf8_length(); i++) {
+      st->print("%c", char_at(i));
+    }
+    st->print(";'");
+  }
+}
+
 // SymbolTable prints this in its statistics
 NOT_PRODUCT(size_t Symbol::_total_count = 0;)
< prev index next >