src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java
changeset 54732 2d012a75d35c
parent 54669 ad45b3802d4e
child 58851 f1e6442241ca
equal deleted inserted replaced
54731:81de17a33575 54732:2d012a75d35c
   281         }
   281         }
   282         return ClassLoader.getSystemClassLoader();
   282         return ClassLoader.getSystemClassLoader();
   283     }
   283     }
   284 
   284 
   285     /**
   285     /**
       
   286      * A Java {@code char} has a maximal UTF8 length of 3.
       
   287      */
       
   288     private static final int MAX_UNICODE_IN_UTF8_LENGTH = 3;
       
   289 
       
   290     /**
       
   291      * {@link DataOutputStream#writeUTF(String)} only supports values whose UTF8 encoding length is
       
   292      * less than 65535.
       
   293      */
       
   294     private static final int MAX_UTF8_PROPERTY_STRING_LENGTH = 65535 / MAX_UNICODE_IN_UTF8_LENGTH;
       
   295 
       
   296     /**
   286      * Serializes the {@linkplain #getSavedProperties() saved system properties} to a byte array for
   297      * Serializes the {@linkplain #getSavedProperties() saved system properties} to a byte array for
   287      * the purpose of {@linkplain #initializeSavedProperties(byte[]) initializing} the initial
   298      * the purpose of {@linkplain #initializeSavedProperties(byte[]) initializing} the initial
   288      * properties in the JVMCI shared library.
   299      * properties in the JVMCI shared library.
   289      */
   300      */
   290     @VMEntryPoint
   301     @VMEntryPoint
   291     private static byte[] serializeSavedProperties() throws IOException {
   302     private static byte[] serializeSavedProperties() throws IOException {
   292         if (IS_IN_NATIVE_IMAGE) {
   303         if (IS_IN_NATIVE_IMAGE) {
   293             throw new InternalError("Can only serialize saved properties in HotSpot runtime");
   304             throw new InternalError("Can only serialize saved properties in HotSpot runtime");
   294         }
   305         }
   295         Map<String, String> props = Services.getSavedProperties();
   306         return serializeProperties(Services.getSavedProperties());
   296 
   307     }
       
   308 
       
   309     private static byte[] serializeProperties(Map<String, String> props) throws IOException {
   297         // Compute size of output on the assumption that
   310         // Compute size of output on the assumption that
   298         // all system properties have ASCII names and values
   311         // all system properties have ASCII names and values
   299         int estimate = 4;
   312         int estimate = 4 + 4;
       
   313         int nonUtf8Props = 0;
   300         for (Map.Entry<String, String> e : props.entrySet()) {
   314         for (Map.Entry<String, String> e : props.entrySet()) {
   301             String name = e.getKey();
   315             String name = e.getKey();
   302             String value = e.getValue();
   316             String value = e.getValue();
   303             estimate += (2 + (name.length())) + (2 + (value.length()));
   317             estimate += (2 + (name.length())) + (2 + (value.length()));
       
   318             if (name.length() > MAX_UTF8_PROPERTY_STRING_LENGTH || value.length() > MAX_UTF8_PROPERTY_STRING_LENGTH) {
       
   319                 nonUtf8Props++;
       
   320             }
   304         }
   321         }
   305 
   322 
   306         ByteArrayOutputStream baos = new ByteArrayOutputStream(estimate);
   323         ByteArrayOutputStream baos = new ByteArrayOutputStream(estimate);
   307         DataOutputStream out = new DataOutputStream(baos);
   324         DataOutputStream out = new DataOutputStream(baos);
   308         out.writeInt(props.size());
   325         out.writeInt(props.size() - nonUtf8Props);
       
   326         out.writeInt(nonUtf8Props);
   309         for (Map.Entry<String, String> e : props.entrySet()) {
   327         for (Map.Entry<String, String> e : props.entrySet()) {
   310             String name = e.getKey();
   328             String name = e.getKey();
   311             String value = e.getValue();
   329             String value = e.getValue();
   312             out.writeUTF(name);
   330             if (name.length() <= MAX_UTF8_PROPERTY_STRING_LENGTH && value.length() <= MAX_UTF8_PROPERTY_STRING_LENGTH) {
   313             out.writeUTF(value);
   331                 out.writeUTF(name);
       
   332                 out.writeUTF(value);
       
   333             }
       
   334         }
       
   335         if (nonUtf8Props != 0) {
       
   336             for (Map.Entry<String, String> e : props.entrySet()) {
       
   337                 String name = e.getKey();
       
   338                 String value = e.getValue();
       
   339                 if (name.length() > MAX_UTF8_PROPERTY_STRING_LENGTH || value.length() > MAX_UTF8_PROPERTY_STRING_LENGTH) {
       
   340                     byte[] utf8Name = name.getBytes("UTF-8");
       
   341                     byte[] utf8Value = value.getBytes("UTF-8");
       
   342                     out.writeInt(utf8Name.length);
       
   343                     out.write(utf8Name);
       
   344                     out.writeInt(utf8Value.length);
       
   345                     out.write(utf8Value);
       
   346                 }
       
   347             }
   314         }
   348         }
   315         return baos.toByteArray();
   349         return baos.toByteArray();
   316     }
   350     }
   317 
   351 
   318     /**
   352     /**
   323     @VMEntryPoint
   357     @VMEntryPoint
   324     private static void initializeSavedProperties(byte[] serializedProperties) throws IOException {
   358     private static void initializeSavedProperties(byte[] serializedProperties) throws IOException {
   325         if (!IS_IN_NATIVE_IMAGE) {
   359         if (!IS_IN_NATIVE_IMAGE) {
   326             throw new InternalError("Can only initialize saved properties in JVMCI shared library runtime");
   360             throw new InternalError("Can only initialize saved properties in JVMCI shared library runtime");
   327         }
   361         }
       
   362         savedProperties = Collections.unmodifiableMap(deserializeProperties(serializedProperties));
       
   363     }
       
   364 
       
   365     private static Map<String, String> deserializeProperties(byte[] serializedProperties) throws IOException {
   328         DataInputStream in = new DataInputStream(new ByteArrayInputStream(serializedProperties));
   366         DataInputStream in = new DataInputStream(new ByteArrayInputStream(serializedProperties));
   329         Map<String, String> props = new HashMap<>(in.readInt());
   367         int utf8Props = in.readInt();
       
   368         int nonUtf8Props = in.readInt();
       
   369         Map<String, String> props = new HashMap<>(utf8Props + nonUtf8Props);
       
   370         int index = 0;
   330         while (in.available() != 0) {
   371         while (in.available() != 0) {
   331             String name = in.readUTF();
   372             if (index < utf8Props) {
   332             String value = in.readUTF();
   373                 String name = in.readUTF();
   333             props.put(name, value);
   374                 String value = in.readUTF();
   334         }
   375                 props.put(name, value);
   335         savedProperties = Collections.unmodifiableMap(props);
   376             } else {
       
   377                 int nameLen = in.readInt();
       
   378                 byte[] nameBytes = new byte[nameLen];
       
   379                 in.read(nameBytes);
       
   380                 int valueLen = in.readInt();
       
   381                 byte[] valueBytes = new byte[valueLen];
       
   382                 in.read(valueBytes);
       
   383                 String name = new String(nameBytes, "UTF-8");
       
   384                 String value = new String(valueBytes, "UTF-8");
       
   385                 props.put(name, value);
       
   386             }
       
   387             index++;
       
   388         }
       
   389         return props;
   336     }
   390     }
   337 }
   391 }