215 //
216 // Notes:
217 // - Even though ATTRIBUTE_END (which might be encoded with a zero byte) is used to
218 // mark the end of the attribute stream, streams will contain zero byte values
219 // in the non-header portion of the attribute data. Thus, detecting a zero byte
220 // is not sufficient to detect the end of an attribute stream.
221 // - ATTRIBUTE_OFFSET represents the number of bytes from the beginning of the region
222 // storing the resources. Thus, in an image this represents the number of bytes
223 // after the index.
224 // - Currently, compressed resources are represented by having a non-zero
225 // ATTRIBUTE_COMPRESSED value. This represents the number of bytes stored in the
226 // image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the
227 // inflated resource in memory. If the ATTRIBUTE_COMPRESSED is zero then the value
228 // of ATTRIBUTE_UNCOMPRESSED represents both the number of bytes in the image and
229 // in memory. In the future, additional compression techniques will be used and
230 // represented differently.
231 // - Package strings include trailing slash and extensions include prefix period.
232 //
233 class ImageLocation {
234 public:
235 enum {
236 ATTRIBUTE_END, // End of attribute stream marker
237 ATTRIBUTE_MODULE, // String table offset of module name
238 ATTRIBUTE_PARENT, // String table offset of resource path parent
239 ATTRIBUTE_BASE, // String table offset of resource path base
240 ATTRIBUTE_EXTENSION, // String table offset of resource path extension
241 ATTRIBUTE_OFFSET, // Container byte offset of resource
242 ATTRIBUTE_COMPRESSED, // In image byte size of the compressed resource
243 ATTRIBUTE_UNCOMPRESSED, // In memory byte size of the uncompressed resource
244 ATTRIBUTE_COUNT // Number of attribute kinds
245 };
246
247 private:
248 // Values of inflated attributes.
249 u8 _attributes[ATTRIBUTE_COUNT];
250
251 // Return the attribute value number of bytes.
252 inline static u1 attribute_length(u1 data) {
253 return (data & 0x7) + 1;
254 }
255
256 // Return the attribute kind.
257 inline static u1 attribute_kind(u1 data) {
258 u1 kind = data >> 3;
259 assert(kind < ATTRIBUTE_COUNT && "invalid attribute kind");
260 return kind;
261 }
262
263 // Return the attribute length.
264 inline static u8 attribute_value(u1* data, u1 n) {
265 assert(0 < n && n <= 8 && "invalid attribute value length");
266 u8 value = 0;
283 }
284
285 // Inflates the attribute stream into individual values stored in the long
286 // array _attributes. This allows an attribute value to be quickly accessed by
287 // direct indexing. Unspecified values default to zero.
288 void set_data(u1* data);
289
290 // Zero all attribute values.
291 void clear_data();
292
293 // Retrieve an attribute value from the inflated array.
294 inline u8 get_attribute(u1 kind) const {
295 assert(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT && "invalid attribute kind");
296 return _attributes[kind];
297 }
298
299 // Retrieve an attribute string value from the inflated array.
300 inline const char* get_attribute(u4 kind, const ImageStrings& strings) const {
301 return strings.get((u4)get_attribute(kind));
302 }
303 };
304
305 // Image file header, starting at offset 0.
306 class ImageHeader {
307 private:
308 u4 _magic; // Image file marker
309 u4 _version; // Image file major version number
310 u4 _flags; // Image file flags
311 u4 _resource_count; // Number of resources in file
312 u4 _table_length; // Number of slots in index tables
313 u4 _locations_size; // Number of bytes in attribute table
314 u4 _strings_size; // Number of bytes in string table
315
316 public:
317 u4 magic() const { return _magic; }
318 u4 magic(Endian* endian) const { return endian->get(_magic); }
319 void set_magic(Endian* endian, u4 magic) { return endian->set(_magic, magic); }
320
321 u4 major_version(Endian* endian) const { return endian->get(_version) >> 16; }
322 u4 minor_version(Endian* endian) const { return endian->get(_version) & 0xFFFF; }
377 void remove(ImageFileReader* image);
378
379 // Determine if image entry is in table.
380 bool contains(ImageFileReader* image);
381 };
382
383 // Manage the image file.
384 // ImageFileReader manages the content of an image file.
385 // Initially, the header of the image file is read for validation. If valid,
386 // values in the header are used calculate the size of the image index. The
387 // index is then memory mapped to allow load on demand and sharing. The
388 // -XX:+MemoryMapImage flag determines if the entire file is loaded (server use.)
389 // An image can be used by Hotspot and multiple reference points in the JDK, thus
390 // it is desirable to share a reader. To accommodate sharing, a share table is
391 // defined (see ImageFileReaderTable in imageFile.cpp) To track the number of
392 // uses, ImageFileReader keeps a use count (_use). Use is incremented when
393 // 'opened' by reference point and decremented when 'closed'. Use of zero
394 // leads the ImageFileReader to be actually closed and discarded.
395 class ImageFileReader {
396 friend class ImageFileReaderTable;
397 private:
398 // Manage a number of image files such that an image can be shared across
399 // multiple uses (ex. loader.)
400 static ImageFileReaderTable _reader_table;
401
402 // true if image should be fully memory mapped.
403 static bool memory_map_image;
404
405 char* _name; // Name of image
406 s4 _use; // Use count
407 int _fd; // File descriptor
408 Endian* _endian; // Endian handler
409 u8 _file_size; // File size in bytes
410 ImageHeader _header; // Image header
411 size_t _index_size; // Total size of index
412 u1* _index_data; // Raw index data
413 s4* _redirect_table; // Perfect hash redirect table
414 u4* _offsets_table; // Location offset table
415 u1* _location_bytes; // Location attributes
416 u1* _string_bytes; // String table
417
418 ImageFileReader(const char* name, bool big_endian);
419 ~ImageFileReader();
420
421 // Compute number of bytes in image file index.
422 inline size_t index_size() {
423 return sizeof(ImageHeader) +
424 table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
425 }
426
427 public:
428 enum {
429 // Image file marker.
430 IMAGE_MAGIC = 0xCAFEDADA,
431 // Endian inverted Image file marker.
432 IMAGE_MAGIC_INVERT = 0xDADAFECA,
433 // Image file major version number.
434 MAJOR_VERSION = 1,
435 // Image file minor version number.
436 MINOR_VERSION = 0
437 };
438
439 // Locate an image if file already open.
440 static ImageFileReader* find_image(const char* name);
441
442 // Open an image file, reuse structure if file already open.
443 static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
444
445 // Close an image file if the file is not in use elsewhere.
446 static void close(ImageFileReader *reader);
447
448 // Return an id for the specified ImageFileReader.
449 static u8 reader_to_ID(ImageFileReader *reader);
450
451 // Validate the image id.
452 static bool id_check(u8 id);
453
454 // Return an id for the specified ImageFileReader.
455 static ImageFileReader* id_to_reader(u8 id);
456
|
215 //
216 // Notes:
217 // - Even though ATTRIBUTE_END (which might be encoded with a zero byte) is used to
218 // mark the end of the attribute stream, streams will contain zero byte values
219 // in the non-header portion of the attribute data. Thus, detecting a zero byte
220 // is not sufficient to detect the end of an attribute stream.
221 // - ATTRIBUTE_OFFSET represents the number of bytes from the beginning of the region
222 // storing the resources. Thus, in an image this represents the number of bytes
223 // after the index.
224 // - Currently, compressed resources are represented by having a non-zero
225 // ATTRIBUTE_COMPRESSED value. This represents the number of bytes stored in the
226 // image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the
227 // inflated resource in memory. If the ATTRIBUTE_COMPRESSED is zero then the value
228 // of ATTRIBUTE_UNCOMPRESSED represents both the number of bytes in the image and
229 // in memory. In the future, additional compression techniques will be used and
230 // represented differently.
231 // - Package strings include trailing slash and extensions include prefix period.
232 //
233 class ImageLocation {
234 public:
235 // See also src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java
236 enum {
237 ATTRIBUTE_END, // End of attribute stream marker
238 ATTRIBUTE_MODULE, // String table offset of module name
239 ATTRIBUTE_PARENT, // String table offset of resource path parent
240 ATTRIBUTE_BASE, // String table offset of resource path base
241 ATTRIBUTE_EXTENSION, // String table offset of resource path extension
242 ATTRIBUTE_OFFSET, // Container byte offset of resource
243 ATTRIBUTE_COMPRESSED, // In-image byte size of the compressed resource
244 ATTRIBUTE_UNCOMPRESSED, // In-memory byte size of the uncompressed resource
245 ATTRIBUTE_PREVIEW_FLAGS, // Flags relating to preview mode resources.
246 ATTRIBUTE_COUNT // Number of attribute kinds
247 };
248
249 // Flag masks for the ATTRIBUTE_PREVIEW_FLAGS attribute. Defined so
250 // that zero is the overwhelmingly common case for normal resources.
251 // See also src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java
252 enum {
253 // Set on a "normal" (non-preview) location if a preview version of
254 // it exists in the same module.
255 FLAGS_HAS_PREVIEW_VERSION = 0x1,
256 // Set on all preview locations in "/modules/xxx/META-INF/preview/..."
257 FLAGS_IS_PREVIEW_VERSION = 0x2,
258 // Set on a preview location if no normal (non-preview) version of
259 // it exists in the same module.
260 FLAGS_IS_PREVIEW_ONLY = 0x4
261 };
262
263 private:
264 // Values of inflated attributes.
265 u8 _attributes[ATTRIBUTE_COUNT];
266
267 // Return the attribute value number of bytes.
268 inline static u1 attribute_length(u1 data) {
269 return (data & 0x7) + 1;
270 }
271
272 // Return the attribute kind.
273 inline static u1 attribute_kind(u1 data) {
274 u1 kind = data >> 3;
275 assert(kind < ATTRIBUTE_COUNT && "invalid attribute kind");
276 return kind;
277 }
278
279 // Return the attribute length.
280 inline static u8 attribute_value(u1* data, u1 n) {
281 assert(0 < n && n <= 8 && "invalid attribute value length");
282 u8 value = 0;
299 }
300
301 // Inflates the attribute stream into individual values stored in the long
302 // array _attributes. This allows an attribute value to be quickly accessed by
303 // direct indexing. Unspecified values default to zero.
304 void set_data(u1* data);
305
306 // Zero all attribute values.
307 void clear_data();
308
309 // Retrieve an attribute value from the inflated array.
310 inline u8 get_attribute(u1 kind) const {
311 assert(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT && "invalid attribute kind");
312 return _attributes[kind];
313 }
314
315 // Retrieve an attribute string value from the inflated array.
316 inline const char* get_attribute(u4 kind, const ImageStrings& strings) const {
317 return strings.get((u4)get_attribute(kind));
318 }
319
320 // Retrieve flags from the ATTRIBUTE_PREVIEW_FLAGS attribute.
321 inline u4 get_preview_flags() const {
322 return (u4) get_attribute(ATTRIBUTE_PREVIEW_FLAGS);
323 }
324 };
325
326 // Image file header, starting at offset 0.
327 class ImageHeader {
328 private:
329 u4 _magic; // Image file marker
330 u4 _version; // Image file major version number
331 u4 _flags; // Image file flags
332 u4 _resource_count; // Number of resources in file
333 u4 _table_length; // Number of slots in index tables
334 u4 _locations_size; // Number of bytes in attribute table
335 u4 _strings_size; // Number of bytes in string table
336
337 public:
338 u4 magic() const { return _magic; }
339 u4 magic(Endian* endian) const { return endian->get(_magic); }
340 void set_magic(Endian* endian, u4 magic) { return endian->set(_magic, magic); }
341
342 u4 major_version(Endian* endian) const { return endian->get(_version) >> 16; }
343 u4 minor_version(Endian* endian) const { return endian->get(_version) & 0xFFFF; }
398 void remove(ImageFileReader* image);
399
400 // Determine if image entry is in table.
401 bool contains(ImageFileReader* image);
402 };
403
404 // Manage the image file.
405 // ImageFileReader manages the content of an image file.
406 // Initially, the header of the image file is read for validation. If valid,
407 // values in the header are used calculate the size of the image index. The
408 // index is then memory mapped to allow load on demand and sharing. The
409 // -XX:+MemoryMapImage flag determines if the entire file is loaded (server use.)
410 // An image can be used by Hotspot and multiple reference points in the JDK, thus
411 // it is desirable to share a reader. To accommodate sharing, a share table is
412 // defined (see ImageFileReaderTable in imageFile.cpp) To track the number of
413 // uses, ImageFileReader keeps a use count (_use). Use is incremented when
414 // 'opened' by reference point and decremented when 'closed'. Use of zero
415 // leads the ImageFileReader to be actually closed and discarded.
416 class ImageFileReader {
417 friend class ImageFileReaderTable;
418 friend class PackageFlags;
419 private:
420 // Manage a number of image files such that an image can be shared across
421 // multiple uses (ex. loader.)
422 static ImageFileReaderTable _reader_table;
423
424 // true if image should be fully memory mapped.
425 static bool memory_map_image;
426
427 char* _name; // Name of image
428 s4 _use; // Use count
429 int _fd; // File descriptor
430 Endian* _endian; // Endian handler
431 u8 _file_size; // File size in bytes
432 ImageHeader _header; // Image header
433 size_t _index_size; // Total size of index
434 u1* _index_data; // Raw index data
435 s4* _redirect_table; // Perfect hash redirect table
436 u4* _offsets_table; // Location offset table
437 u1* _location_bytes; // Location attributes
438 u1* _string_bytes; // String table
439
440 ImageFileReader(const char* name, bool big_endian);
441 ~ImageFileReader();
442
443 // Compute number of bytes in image file index.
444 inline size_t index_size() {
445 return sizeof(ImageHeader) +
446 table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
447 }
448
449 public:
450 enum {
451 // Image file marker.
452 IMAGE_MAGIC = 0xCAFEDADA,
453 // Endian inverted Image file marker.
454 IMAGE_MAGIC_INVERT = 0xDADAFECA,
455 // Image file major version number.
456 MAJOR_VERSION = 1,
457 // Image file minor version number.
458 MINOR_VERSION = 1
459 };
460
461 // Locate an image if file already open.
462 static ImageFileReader* find_image(const char* name);
463
464 // Open an image file, reuse structure if file already open.
465 static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
466
467 // Close an image file if the file is not in use elsewhere.
468 static void close(ImageFileReader *reader);
469
470 // Return an id for the specified ImageFileReader.
471 static u8 reader_to_ID(ImageFileReader *reader);
472
473 // Validate the image id.
474 static bool id_check(u8 id);
475
476 // Return an id for the specified ImageFileReader.
477 static ImageFileReader* id_to_reader(u8 id);
478
|