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; }
374 void add(ImageFileReader* image);
375
376 // Remove an image entry from the table.
377 void remove(ImageFileReader* image);
378 };
379
380 // Manage the image file.
381 // ImageFileReader manages the content of an image file.
382 // Initially, the header of the image file is read for validation. If valid,
383 // values in the header are used calculate the size of the image index. The
384 // index is then memory mapped to allow load on demand and sharing. The
385 // -XX:+MemoryMapImage flag determines if the entire file is loaded (server use.)
386 // An image can be used by Hotspot and multiple reference points in the JDK, thus
387 // it is desirable to share a reader. To accommodate sharing, a share table is
388 // defined (see ImageFileReaderTable in imageFile.cpp) To track the number of
389 // uses, ImageFileReader keeps a use count (_use). Use is incremented when
390 // 'opened' by reference point and decremented when 'closed'. Use of zero
391 // leads the ImageFileReader to be actually closed and discarded.
392 class ImageFileReader {
393 friend class ImageFileReaderTable;
394 private:
395 // Manage a number of image files such that an image can be shared across
396 // multiple uses (ex. loader.)
397 static ImageFileReaderTable _reader_table;
398
399 // true if image should be fully memory mapped.
400 static bool memory_map_image;
401
402 char* _name; // Name of image
403 s4 _use; // Use count
404 int _fd; // File descriptor
405 Endian* _endian; // Endian handler
406 u8 _file_size; // File size in bytes
407 ImageHeader _header; // Image header
408 size_t _index_size; // Total size of index
409 u1* _index_data; // Raw index data
410 s4* _redirect_table; // Perfect hash redirect table
411 u4* _offsets_table; // Location offset table
412 u1* _location_bytes; // Location attributes
413 u1* _string_bytes; // String table
414
415 ImageFileReader(const char* name, bool big_endian);
416 ~ImageFileReader();
417
418 // Compute number of bytes in image file index.
419 inline size_t index_size() {
420 return sizeof(ImageHeader) +
421 table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
422 }
423
424 public:
425 enum {
426 // Image file marker.
427 IMAGE_MAGIC = 0xCAFEDADA,
428 // Endian inverted Image file marker.
429 IMAGE_MAGIC_INVERT = 0xDADAFECA,
430 // Image file major version number.
431 MAJOR_VERSION = 1,
432 // Image file minor version number.
433 MINOR_VERSION = 0
434 };
435
436 // Locate an image if file already open.
437 static ImageFileReader* find_image(const char* name);
438
439 // Open an image file, reuse structure if file already open.
440 static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
441
442 // Close an image file if the file is not in use elsewhere.
443 static void close(ImageFileReader *reader);
444
445 // Open image file for read access.
446 bool open();
447
448 // Close image file.
449 void close();
450
451 // Read directly from the file.
452 bool read_at(u1* data, u8 size, u8 offset) const;
453
|
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; }
395 void add(ImageFileReader* image);
396
397 // Remove an image entry from the table.
398 void remove(ImageFileReader* image);
399 };
400
401 // Manage the image file.
402 // ImageFileReader manages the content of an image file.
403 // Initially, the header of the image file is read for validation. If valid,
404 // values in the header are used calculate the size of the image index. The
405 // index is then memory mapped to allow load on demand and sharing. The
406 // -XX:+MemoryMapImage flag determines if the entire file is loaded (server use.)
407 // An image can be used by Hotspot and multiple reference points in the JDK, thus
408 // it is desirable to share a reader. To accommodate sharing, a share table is
409 // defined (see ImageFileReaderTable in imageFile.cpp) To track the number of
410 // uses, ImageFileReader keeps a use count (_use). Use is incremented when
411 // 'opened' by reference point and decremented when 'closed'. Use of zero
412 // leads the ImageFileReader to be actually closed and discarded.
413 class ImageFileReader {
414 friend class ImageFileReaderTable;
415 friend class PackageFlags;
416 private:
417 // Manage a number of image files such that an image can be shared across
418 // multiple uses (ex. loader.)
419 static ImageFileReaderTable _reader_table;
420
421 // true if image should be fully memory mapped.
422 static bool memory_map_image;
423
424 char* _name; // Name of image
425 s4 _use; // Use count
426 int _fd; // File descriptor
427 Endian* _endian; // Endian handler
428 u8 _file_size; // File size in bytes
429 ImageHeader _header; // Image header
430 size_t _index_size; // Total size of index
431 u1* _index_data; // Raw index data
432 s4* _redirect_table; // Perfect hash redirect table
433 u4* _offsets_table; // Location offset table
434 u1* _location_bytes; // Location attributes
435 u1* _string_bytes; // String table
436
437 ImageFileReader(const char* name, bool big_endian);
438 ~ImageFileReader();
439
440 // Compute number of bytes in image file index.
441 inline size_t index_size() {
442 return sizeof(ImageHeader) +
443 table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
444 }
445
446 public:
447 enum {
448 // Image file marker.
449 IMAGE_MAGIC = 0xCAFEDADA,
450 // Endian inverted Image file marker.
451 IMAGE_MAGIC_INVERT = 0xDADAFECA,
452 // Image file major version number.
453 MAJOR_VERSION = 1,
454 // Image file minor version number.
455 MINOR_VERSION = 1
456 };
457
458 // Locate an image if file already open.
459 static ImageFileReader* find_image(const char* name);
460
461 // Open an image file, reuse structure if file already open.
462 static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
463
464 // Close an image file if the file is not in use elsewhere.
465 static void close(ImageFileReader *reader);
466
467 // Open image file for read access.
468 bool open();
469
470 // Close image file.
471 void close();
472
473 // Read directly from the file.
474 bool read_at(u1* data, u8 size, u8 offset) const;
475
|