Projects
openEuler:24.03:SP1:Everything
openjdk-1.8.0
_service:tar_scm:0041-Reuse-translet-in-XSLTC-f...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:0041-Reuse-translet-in-XSLTC-for-specjvm-xml-transform.patch of Package openjdk-1.8.0
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
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2