Skip to content
Permalink
Browse files

8230199: consolidate signature parsing code in HotSpot sources

Add a new Signature class to support basic signature queries and enhance SignatureStream class to parse field signatures in addition to methods.

Co-authored-by: John Rose <john.r.rose@oracle.com>
Reviewed-by: coleenp, dholmes, fparain, hseigel
  • Loading branch information
Lois Foltan and rose00 committed Feb 6, 2020
1 parent 2ede36b commit d19a396e96cee4bb4facb268c723f23cbae83351
Showing with 1,382 additions and 1,486 deletions.
  1. +6 −18 src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp
  2. +6 −18 src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp
  3. +6 −18 src/hotspot/cpu/s390/sharedRuntime_s390.cpp
  4. +6 −18 src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp
  5. +6 −18 src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
  6. +6 −18 src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp
  7. +8 −8 src/hotspot/share/c1/c1_ValueMap.cpp
  8. +9 −10 src/hotspot/share/ci/ciEnv.cpp
  9. +2 −2 src/hotspot/share/ci/ciField.cpp
  10. +2 −1 src/hotspot/share/ci/ciKlass.hpp
  11. +14 −28 src/hotspot/share/ci/ciObjArrayKlass.cpp
  12. +6 −12 src/hotspot/share/ci/ciObjectFactory.cpp
  13. +4 −4 src/hotspot/share/ci/ciSignature.cpp
  14. +8 −24 src/hotspot/share/classfile/classFileParser.cpp
  15. +2 −3 src/hotspot/share/classfile/classListParser.cpp
  16. +2 −3 src/hotspot/share/classfile/defaultMethods.cpp
  17. +1 −2 src/hotspot/share/classfile/placeholders.cpp
  18. +1 −2 src/hotspot/share/classfile/stackMapTable.cpp
  19. +62 −64 src/hotspot/share/classfile/systemDictionary.cpp
  20. +1 −5 src/hotspot/share/classfile/systemDictionary.hpp
  21. +24 −22 src/hotspot/share/classfile/verificationType.cpp
  22. +4 −18 src/hotspot/share/classfile/vmSymbols.cpp
  23. +1 −3 src/hotspot/share/classfile/vmSymbols.hpp
  24. +5 −7 src/hotspot/share/code/nmethod.cpp
  25. +3 −2 src/hotspot/share/compiler/methodMatcher.cpp
  26. +1 −2 src/hotspot/share/interpreter/bytecode.cpp
  27. +6 −5 src/hotspot/share/interpreter/bytecodeUtils.cpp
  28. +2 −2 src/hotspot/share/interpreter/interpreterRuntime.cpp
  29. +2 −2 src/hotspot/share/interpreter/oopMapCache.cpp
  30. +2 −2 src/hotspot/share/interpreter/rewriter.cpp
  31. +5 −7 src/hotspot/share/jvmci/compilerRuntime.cpp
  32. +18 −23 src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
  33. +29 −17 src/hotspot/share/jvmci/jvmciCompilerToVM.hpp
  34. +1 −1 src/hotspot/share/oops/constMethod.cpp
  35. +3 −4 src/hotspot/share/oops/constantPool.cpp
  36. +44 −47 src/hotspot/share/oops/generateOopMap.cpp
  37. +2 −2 src/hotspot/share/oops/generateOopMap.hpp
  38. +16 −12 src/hotspot/share/oops/method.cpp
  39. +4 −2 src/hotspot/share/oops/method.hpp
  40. +18 −23 src/hotspot/share/oops/methodData.cpp
  41. +49 −39 src/hotspot/share/oops/symbol.cpp
  42. +22 −8 src/hotspot/share/oops/symbol.hpp
  43. +73 −183 src/hotspot/share/prims/jni.cpp
  44. +3 −3 src/hotspot/share/prims/jvmtiImpl.cpp
  45. +33 −83 src/hotspot/share/prims/methodHandles.cpp
  46. +2 −2 src/hotspot/share/prims/methodHandles.hpp
  47. +11 −24 src/hotspot/share/runtime/deoptimization.cpp
  48. +1 −2 src/hotspot/share/runtime/fieldDescriptor.hpp
  49. +2 −2 src/hotspot/share/runtime/fieldDescriptor.inline.hpp
  50. +31 −27 src/hotspot/share/runtime/frame.cpp
  51. +31 −43 src/hotspot/share/runtime/javaCalls.cpp
  52. +3 −2 src/hotspot/share/runtime/reflection.cpp
  53. +6 −31 src/hotspot/share/runtime/sharedRuntime.cpp
  54. +315 −291 src/hotspot/share/runtime/signature.cpp
  55. +408 −248 src/hotspot/share/runtime/signature.hpp
  56. +19 −1 src/hotspot/share/utilities/globalDefinitions.cpp
  57. +25 −18 src/hotspot/share/utilities/globalDefinitions.hpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -1333,28 +1333,16 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// Arrays are passed as int, elem* pair
out_sig_bt[argc++] = T_INT;
out_sig_bt[argc++] = T_ADDRESS;
Symbol* atype = ss.as_symbol();
const char* at = atype->as_C_string();
if (strlen(at) == 2) {
assert(at[0] == '[', "must be");
switch (at[1]) {
case 'B': in_elem_bt[i] = T_BYTE; break;
case 'C': in_elem_bt[i] = T_CHAR; break;
case 'D': in_elem_bt[i] = T_DOUBLE; break;
case 'F': in_elem_bt[i] = T_FLOAT; break;
case 'I': in_elem_bt[i] = T_INT; break;
case 'J': in_elem_bt[i] = T_LONG; break;
case 'S': in_elem_bt[i] = T_SHORT; break;
case 'Z': in_elem_bt[i] = T_BOOLEAN; break;
default: ShouldNotReachHere();
}
}
ss.skip_array_prefix(1); // skip one '['
assert(ss.is_primitive(), "primitive type expected");
in_elem_bt[i] = ss.type();
} else {
out_sig_bt[argc++] = in_sig_bt[i];
in_elem_bt[i] = T_VOID;
}
if (in_sig_bt[i] != T_VOID) {
assert(in_sig_bt[i] == ss.type(), "must match");
assert(in_sig_bt[i] == ss.type() ||
in_sig_bt[i] == T_ARRAY, "must match");
ss.next();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -1934,27 +1934,15 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
for (int i = 0; i < total_in_args ; i++, o++) {
if (in_sig_bt[i] == T_ARRAY) {
// Arrays are passed as int, elem* pair
Symbol* atype = ss.as_symbol();
const char* at = atype->as_C_string();
if (strlen(at) == 2) {
assert(at[0] == '[', "must be");
switch (at[1]) {
case 'B': in_elem_bt[o] = T_BYTE; break;
case 'C': in_elem_bt[o] = T_CHAR; break;
case 'D': in_elem_bt[o] = T_DOUBLE; break;
case 'F': in_elem_bt[o] = T_FLOAT; break;
case 'I': in_elem_bt[o] = T_INT; break;
case 'J': in_elem_bt[o] = T_LONG; break;
case 'S': in_elem_bt[o] = T_SHORT; break;
case 'Z': in_elem_bt[o] = T_BOOLEAN; break;
default: ShouldNotReachHere();
}
}
ss.skip_array_prefix(1); // skip one '['
assert(ss.is_primitive(), "primitive type expected");
in_elem_bt[o] = ss.type();
} else {
in_elem_bt[o] = T_VOID;
}
if (in_sig_bt[i] != T_VOID) {
assert(in_sig_bt[i] == ss.type(), "must match");
assert(in_sig_bt[i] == ss.type() ||
in_sig_bt[i] == T_ARRAY, "must match");
ss.next();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -1626,27 +1626,15 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
for (int i = 0; i < total_in_args; i++, o++) {
if (in_sig_bt[i] == T_ARRAY) {
// Arrays are passed as tuples (int, elem*).
Symbol* atype = ss.as_symbol();
const char* at = atype->as_C_string();
if (strlen(at) == 2) {
assert(at[0] == '[', "must be");
switch (at[1]) {
case 'B': in_elem_bt[o] = T_BYTE; break;
case 'C': in_elem_bt[o] = T_CHAR; break;
case 'D': in_elem_bt[o] = T_DOUBLE; break;
case 'F': in_elem_bt[o] = T_FLOAT; break;
case 'I': in_elem_bt[o] = T_INT; break;
case 'J': in_elem_bt[o] = T_LONG; break;
case 'S': in_elem_bt[o] = T_SHORT; break;
case 'Z': in_elem_bt[o] = T_BOOLEAN; break;
default: ShouldNotReachHere();
}
}
ss.skip_array_prefix(1); // skip one '['
assert(ss.is_primitive(), "primitive type expected");
in_elem_bt[o] = ss.type();
} else {
in_elem_bt[o] = T_VOID;
}
if (in_sig_bt[i] != T_VOID) {
assert(in_sig_bt[i] == ss.type(), "must match");
assert(in_sig_bt[i] == ss.type() ||
in_sig_bt[i] == T_ARRAY, "must match");
ss.next();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1907,28 +1907,16 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// Arrays are passed as int, elem* pair
out_sig_bt[argc++] = T_INT;
out_sig_bt[argc++] = T_ADDRESS;
Symbol* atype = ss.as_symbol();
const char* at = atype->as_C_string();
if (strlen(at) == 2) {
assert(at[0] == '[', "must be");
switch (at[1]) {
case 'B': in_elem_bt[i] = T_BYTE; break;
case 'C': in_elem_bt[i] = T_CHAR; break;
case 'D': in_elem_bt[i] = T_DOUBLE; break;
case 'F': in_elem_bt[i] = T_FLOAT; break;
case 'I': in_elem_bt[i] = T_INT; break;
case 'J': in_elem_bt[i] = T_LONG; break;
case 'S': in_elem_bt[i] = T_SHORT; break;
case 'Z': in_elem_bt[i] = T_BOOLEAN; break;
default: ShouldNotReachHere();
}
}
ss.skip_array_prefix(1); // skip one '['
assert(ss.is_primitive(), "primitive type expected");
in_elem_bt[i] = ss.type();
} else {
out_sig_bt[argc++] = in_sig_bt[i];
in_elem_bt[i] = T_VOID;
}
if (in_sig_bt[i] != T_VOID) {
assert(in_sig_bt[i] == ss.type(), "must match");
assert(in_sig_bt[i] == ss.type() ||
in_sig_bt[i] == T_ARRAY, "must match");
ss.next();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1697,28 +1697,16 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// Arrays are passed as int, elem* pair
out_sig_bt[argc++] = T_INT;
out_sig_bt[argc++] = T_ADDRESS;
Symbol* atype = ss.as_symbol();
const char* at = atype->as_C_string();
if (strlen(at) == 2) {
assert(at[0] == '[', "must be");
switch (at[1]) {
case 'B': in_elem_bt[i] = T_BYTE; break;
case 'C': in_elem_bt[i] = T_CHAR; break;
case 'D': in_elem_bt[i] = T_DOUBLE; break;
case 'F': in_elem_bt[i] = T_FLOAT; break;
case 'I': in_elem_bt[i] = T_INT; break;
case 'J': in_elem_bt[i] = T_LONG; break;
case 'S': in_elem_bt[i] = T_SHORT; break;
case 'Z': in_elem_bt[i] = T_BOOLEAN; break;
default: ShouldNotReachHere();
}
}
ss.skip_array_prefix(1); // skip one '['
assert(ss.is_primitive(), "primitive type expected");
in_elem_bt[i] = ss.type();
} else {
out_sig_bt[argc++] = in_sig_bt[i];
in_elem_bt[i] = T_VOID;
}
if (in_sig_bt[i] != T_VOID) {
assert(in_sig_bt[i] == ss.type(), "must match");
assert(in_sig_bt[i] == ss.type() ||
in_sig_bt[i] == T_ARRAY, "must match");
ss.next();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2002,28 +2002,16 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// Arrays are passed as int, elem* pair
out_sig_bt[argc++] = T_INT;
out_sig_bt[argc++] = T_ADDRESS;
Symbol* atype = ss.as_symbol();
const char* at = atype->as_C_string();
if (strlen(at) == 2) {
assert(at[0] == '[', "must be");
switch (at[1]) {
case 'B': in_elem_bt[i] = T_BYTE; break;
case 'C': in_elem_bt[i] = T_CHAR; break;
case 'D': in_elem_bt[i] = T_DOUBLE; break;
case 'F': in_elem_bt[i] = T_FLOAT; break;
case 'I': in_elem_bt[i] = T_INT; break;
case 'J': in_elem_bt[i] = T_LONG; break;
case 'S': in_elem_bt[i] = T_SHORT; break;
case 'Z': in_elem_bt[i] = T_BOOLEAN; break;
default: ShouldNotReachHere();
}
}
ss.skip_array_prefix(1); // skip one '['
assert(ss.is_primitive(), "primitive type expected");
in_elem_bt[i] = ss.type();
} else {
out_sig_bt[argc++] = in_sig_bt[i];
in_elem_bt[i] = T_VOID;
}
if (in_sig_bt[i] != T_VOID) {
assert(in_sig_bt[i] == ss.type(), "must match");
assert(in_sig_bt[i] == ss.type() ||
in_sig_bt[i] == T_ARRAY, "must match");
ss.next();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -265,8 +265,8 @@ class ShortLoopOptimizer : public ValueNumberingVisitor {
GlobalValueNumbering* _gvn;
BlockList _loop_blocks;
bool _too_complicated_loop;
bool _has_field_store[T_ARRAY + 1];
bool _has_indexed_store[T_ARRAY + 1];
bool _has_field_store[T_VOID];
bool _has_indexed_store[T_VOID];

// simplified access to methods of GlobalValueNumbering
ValueMap* current_map() { return _gvn->current_map(); }
@@ -276,12 +276,12 @@ class ShortLoopOptimizer : public ValueNumberingVisitor {
void kill_memory() { _too_complicated_loop = true; }
void kill_field(ciField* field, bool all_offsets) {
current_map()->kill_field(field, all_offsets);
assert(field->type()->basic_type() >= 0 && field->type()->basic_type() <= T_ARRAY, "Invalid type");
assert(field->type()->basic_type() >= 0 && field->type()->basic_type() < T_VOID, "Invalid type");
_has_field_store[field->type()->basic_type()] = true;
}
void kill_array(ValueType* type) {
current_map()->kill_array(type);
BasicType basic_type = as_BasicType(type); assert(basic_type >= 0 && basic_type <= T_ARRAY, "Invalid type");
BasicType basic_type = as_BasicType(type); assert(basic_type >= 0 && basic_type < T_VOID, "Invalid type");
_has_indexed_store[basic_type] = true;
}

@@ -291,19 +291,19 @@ class ShortLoopOptimizer : public ValueNumberingVisitor {
, _loop_blocks(ValueMapMaxLoopSize)
, _too_complicated_loop(false)
{
for (int i=0; i<= T_ARRAY; i++){
for (int i = 0; i < T_VOID; i++) {
_has_field_store[i] = false;
_has_indexed_store[i] = false;
}
}

bool has_field_store(BasicType type) {
assert(type >= 0 && type <= T_ARRAY, "Invalid type");
assert(type >= 0 && type < T_VOID, "Invalid type");
return _has_field_store[type];
}

bool has_indexed_store(BasicType type) {
assert(type >= 0 && type <= T_ARRAY, "Invalid type");
assert(type >= 0 && type < T_VOID, "Invalid type");
return _has_indexed_store[type];
}

@@ -413,12 +413,10 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,

// Now we need to check the SystemDictionary
Symbol* sym = name->get_symbol();
if (sym->char_at(0) == JVM_SIGNATURE_CLASS &&
sym->char_at(sym->utf8_length()-1) == JVM_SIGNATURE_ENDCLASS) {
if (Signature::has_envelope(sym)) {
// This is a name from a signature. Strip off the trimmings.
// Call recursive to keep scope of strippedsym.
TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
sym->utf8_length()-2);
TempNewSymbol strippedsym = Signature::strip_envelope(sym);
ciSymbol* strippedname = get_symbol(strippedsym);
return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local);
}
@@ -466,18 +464,17 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
// we must build an array type around it. The CI requires array klasses
// to be loaded if their element klasses are loaded, except when memory
// is exhausted.
if (sym->char_at(0) == JVM_SIGNATURE_ARRAY &&
if (Signature::is_array(sym) &&
(sym->char_at(1) == JVM_SIGNATURE_ARRAY || sym->char_at(1) == JVM_SIGNATURE_CLASS)) {
// We have an unloaded array.
// Build it on the fly if the element class exists.
TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
sym->utf8_length()-1);

SignatureStream ss(sym, false);
ss.skip_array_prefix(1);
// Get element ciKlass recursively.
ciKlass* elem_klass =
get_klass_by_name_impl(accessing_klass,
cpool,
get_symbol(elem_sym),
get_symbol(ss.as_symbol()),
require_local);
if (elem_klass != NULL && elem_klass->is_loaded()) {
// Now make an array for it
@@ -609,7 +606,7 @@ ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool,
}
BasicType bt = T_OBJECT;
if (cpool->tag_at(index).is_dynamic_constant())
bt = FieldType::basic_type(cpool->uncached_signature_ref_at(index));
bt = Signature::basic_type(cpool->uncached_signature_ref_at(index));
if (is_reference_type(bt)) {
} else {
// we have to unbox the primitive value
@@ -791,6 +788,8 @@ Method* ciEnv::lookup_method(ciInstanceKlass* accessor,
ciMethod* ciEnv::get_method_by_index_impl(const constantPoolHandle& cpool,
int index, Bytecodes::Code bc,
ciInstanceKlass* accessor) {
assert(cpool.not_null(), "need constant pool");
assert(accessor != NULL, "need origin of access");
if (bc == Bytecodes::_invokedynamic) {
ConstantPoolCacheEntry* cpce = cpool->invokedynamic_cp_cache_entry_at(index);
bool is_resolved = !cpce->is_f1_null();
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -86,7 +86,7 @@ ciField::ciField(ciInstanceKlass* klass, int index) :
Symbol* signature = cpool->symbol_at(sig_index);
_signature = ciEnv::current(THREAD)->get_symbol(signature);

BasicType field_type = FieldType::basic_type(signature);
BasicType field_type = Signature::basic_type(signature);

// If the field is a pointer type, get the klass of the
// field.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@ class ciKlass : public ciType {
friend class ciMethod;
friend class ciMethodData;
friend class ciObjArrayKlass;
friend class ciSignature;
friend class ciReceiverTypeData;

private:

0 comments on commit d19a396

Please sign in to comment.