1 Star 0 Fork 81

Alex Gao/openjdk-1.8.0

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
0041-Reuse-translet-in-XSLTC-for-specjvm-xml-transform.patch 9.19 KB
一键复制 编辑 原始数据 按行查看 历史
DXwangg 提交于 2023-09-26 09:10 . Add feature and bug fix for 8u382
Date: Fri, 9 Jun 2023 10:29:38 +0800
Subject: Reuse translet in XSLTC for XML
---
.../share/vm/classfile/classFileParser.cpp | 52 +++++++++++-
.../share/vm/classfile/classFileParser.hpp | 2 +-
hotspot/src/share/vm/classfile/vmSymbols.hpp | 4 +-
hotspot/src/share/vm/runtime/arguments.cpp | 2 +
hotspot/src/share/vm/runtime/arguments.hpp | 3 +
.../src/share/vm/utilities/accessFlags.hpp | 1 +
7 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index d8e99e622..b9fde38dc 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -59,12 +59,13 @@
#include "runtime/reflection.hpp"
#include "runtime/signature.hpp"
#include "runtime/timer.hpp"
+#include "runtime/arguments.hpp"
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"
#include "utilities/array.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/ostream.hpp"
-
+#include "interpreter/bytecodeStream.hpp"
// We generally try to create the oops directly when parsing, rather than
// allocating temporary data structures and copying the bytes twice. A
// temporary area is only needed when parsing utf8 entries in the constant
@@ -2556,6 +2557,7 @@ Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
ClassFileStream* cfs = stream();
cfs->guarantee_more(2, CHECK_NULL); // length
u2 length = cfs->get_u2_fast();
+ Method* initializerMethod = NULL;
if (length == 0) {
_methods = Universe::the_empty_method_array();
} else {
@@ -2570,6 +2572,9 @@ Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
if (method->is_final()) {
*has_final_method = true;
}
+ if (method->name()== vmSymbols::object_initializer_name()) {
+ initializerMethod = method();
+ }
// declares_default_methods: declares concrete instance methods, any access flags
// used for interface initialization, and default method inheritance analysis
if (is_interface && !(*declares_default_methods)
@@ -2606,6 +2611,11 @@ Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
name->as_C_string(), sig->as_klass_external_name(), CHECK_NULL);
}
}
+
+ if (Arguments::transletEnhance()) {
+ bool isClassMatched = (_class_name == vmSymbols::transformerFactoryImpl_class_name());
+ if(isClassMatched) modify_fields_value(initializerMethod, vmSymbols::transformer_generateTranslet_field_name(), vmSymbols::transformer_autoTranslet_field_name(), Bytecodes::_iconst_1, CHECK_NULL);
+ }
}
return _methods;
}
@@ -5421,6 +5431,46 @@ char* ClassFileParser::skip_over_field_signature(char* signature,
return NULL;
}
+// This function sets the class's specific fields to a fixed value, ie: targetFieldName1 and targetFieldName2.
+// initializerMethod is the class's "<init>" method, should not be NULL.
+// For performance, two fields can be set at the same time. You can also set only one field, just set targetFieldName2 to NULL.
+// Bytecodes::Code can be bytecode between iconst_0 and dconst_0, range is 0x03 ~ 0x0f.
+void ClassFileParser::modify_fields_value(Method* initializerMethod, Symbol* targetFieldName1, Symbol* targetFieldName2, Bytecodes::Code targetCode, TRAPS) {
+ assert(initializerMethod != NULL, "The method can't be NULL.");
+ assert(initializerMethod->name() == vmSymbols::object_initializer_name(), "The method must be <init>.");
+ assert(targetFieldName1 != NULL, "At least targetFieldName1 can't be NULL.");
+ assert(targetCode >= Bytecodes::_iconst_0 && targetCode <= Bytecodes::_dconst_1, "The primitive constant's value range is 0x03 ~ 0x0f.");
+
+ ResourceMark rm(THREAD);
+ methodHandle mh(initializerMethod);
+ BytecodeStream bcs(mh);
+ while (!bcs.is_last_bytecode()) {
+ Bytecodes::Code code = bcs.next();
+ if (code == Bytecodes::_putfield) {
+ address p = bcs.bcp();
+ // get field index
+ int index = Bytes::get_Java_u2(p + 1);
+ Symbol *name = _cp->name_ref_at(index);
+ if (name == targetFieldName1) {
+ p = p - 1;
+ *(u1 *) p = (u1) targetCode;
+ }
+ if ((targetFieldName2 != NULL) && (name == targetFieldName2)) {
+ p = p - 1;
+ *(u1 *) p = (u1) targetCode;
+ }
+ }
+ }
+ _has_vanilla_constructor = false;
+ AccessFlags flags = mh()->access_flags();
+ flags.clear_has_vanilla_constructor();
+ if (mh->is_vanilla_constructor()) {
+ _has_vanilla_constructor = true;
+ flags.set_has_vanilla_constructor();
+ }
+ mh()->set_access_flags(flags);
+}
+
#if INCLUDE_JFR
// Caller responsible for ResourceMark
diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp
index dfb56c990..1900f0abf 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp
@@ -391,7 +391,7 @@ PRAGMA_DIAG_POP
bool verify_unqualified_name(char* name, unsigned int length, int type);
char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);
char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
-
+ void modify_fields_value(Method* initializerMethod, Symbol* targetFieldName1, Symbol* targetFieldName2, Bytecodes::Code targetCode, TRAPS);
bool is_anonymous() {
assert(EnableInvokeDynamic || _host_klass.is_null(), "");
return _host_klass.not_null();
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index 5f2a9a720..494fd9bdf 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -422,7 +422,9 @@
template(resolved_references_name, "<resolved_references>") \
template(referencequeue_null_name, "NULL") \
template(referencequeue_enqueued_name, "ENQUEUED") \
- \
+ template(transformerFactoryImpl_class_name, "com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl") \
+ template(transformer_generateTranslet_field_name, "_generateTranslet") \
+ template(transformer_autoTranslet_field_name, "_autoTranslet") \
/* non-intrinsic name/signature pairs: */ \
template(register_method_name, "register") \
do_alias(register_method_signature, object_void_signature) \
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index 43fdd0b49..0c8a4012a 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -149,6 +149,8 @@ SystemProperty *Arguments::_sun_boot_class_path = NULL;
char* Arguments::_meta_index_path = NULL;
char* Arguments::_meta_index_dir = NULL;
+bool Arguments::_transletEnhance = false;
+
// Check if head of 'option' matches 'name', and sets 'tail' remaining part of option string
static bool match_option(const JavaVMOption *option, const char* name,
diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp
index 88741e8c3..4f7232e48 100644
--- a/hotspot/src/share/vm/runtime/arguments.hpp
+++ b/hotspot/src/share/vm/runtime/arguments.hpp
@@ -267,6 +267,7 @@ class Arguments : AllStatic {
static char* _meta_index_path;
static char* _meta_index_dir;
+ static bool _transletEnhance;
// java.vendor.url.bug, bug reporting URL for fatal errors.
static const char* _java_vendor_url_bug;
@@ -633,6 +634,8 @@ class Arguments : AllStatic {
static Mode mode() { return _mode; }
static bool is_interpreter_only() { return mode() == _int; }
+ static void set_transletEnhance(bool arg) { _transletEnhance = arg; }
+ static bool transletEnhance() { return _transletEnhance; }
// Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid.
static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen);
diff --git a/hotspot/src/share/vm/utilities/accessFlags.hpp b/hotspot/src/share/vm/utilities/accessFlags.hpp
index bc56262d1..b20f0f740 100644
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp
@@ -209,6 +209,7 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC {
void clear_not_c2_osr_compilable() { atomic_clear_bits(JVM_ACC_NOT_C2_OSR_COMPILABLE); }
// Klass* flags
void set_has_vanilla_constructor() { atomic_set_bits(JVM_ACC_HAS_VANILLA_CONSTRUCTOR); }
+ void clear_has_vanilla_constructor() { atomic_clear_bits(JVM_ACC_HAS_VANILLA_CONSTRUCTOR); }
void set_has_finalizer() { atomic_set_bits(JVM_ACC_HAS_FINALIZER); }
void set_has_final_method() { atomic_set_bits(JVM_ACC_HAS_FINAL_METHOD); }
void set_is_cloneable() { atomic_set_bits(JVM_ACC_IS_CLONEABLE); }
--
2.22.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/gaoxiang90/openjdk-1.8.0.git
git@gitee.com:gaoxiang90/openjdk-1.8.0.git
gaoxiang90
openjdk-1.8.0
openjdk-1.8.0
master

搜索帮助