-
Notifications
You must be signed in to change notification settings - Fork 62
/
Inspector.rst
2492 lines (2064 loc) · 114 KB
/
Inspector.rst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
The Maxine Inspector
====================
The Maxine Inspector is the essential all-in-one companion tool for Open Source Maxine VM development.
It plays many roles:
- object, class, and method browser;
- code views include disassembled machine code, disassembled bytecode, and source;
- low-level debugger (imagine gdb or dbx) with visual displays of threads, registers, stacks, stack frames, thread local values, breakpoints, memory watchpoints, etc.;
- intermediate representation debugger;
- source-level Java debugger (eventually); and
- serviceability agent (eventually).
`This short (5 minute) 2009 video <https://youtu.be/ZOq2y5fTaHc>`__ describes the goals of the inspector and highlights some of the ways in which it makes Maxine VM development highly productive.
Please be aware that the Inspector is very much a work in progress, as is the Maxine VM itself.
The two have co-evolved and will continue to do so as the design of the VM matures and the concerns of the developers expand.
Functionality is constantly being improved and extended, so there are already places where the current system differs from what you will find here.
More discussion and more detailed documentation follows below.
Goals
-----
In addition to enhancing the productivity of our own development team, the Maxine Inspector is part of our strategic goal of making VM experimentation more accessible to a wider audience.
By leveraging the meta-circularity of the VM itself (and sharing a great deal of the VM's source code), the Inspector makes it possible to visualize concisely many aspects of VM state that are elusive and widely distributed in other systems.
These same advantages also make it possible to debug the VM with a single tool, highly specialized for this purpose.
Background and Rationale
------------------------
Debugging virtual machines (VMs) presents unique challenges, expecially for a meta-circular VM, such as Maxine, that is self-implemented in the same language it implements.
Making sense of Maxine's runtime state requires interaction simultaneously at the source, bytecode, and machine code abstraction levels, and it must leverage knowledge of the VM's design.
Specific issues include:
- Maxine VM code must be largely optimized statically, not only for
ordinary performance reasons, but also in order to be able to
bootstrap the VM at all.
- Dynamic optimization at runtime can be applied to the VM's own
implementation, not just application code.
- Mapping optimized code locations back to bytecode and source
locations is not generally possible without onerous limitations.
- Dynamically de-optimizing code for debugging can be effective for
application code, but only when the VM can be assumed correct.
- Debugging the VM itself, however, requires scrutinizing its
lowest-level, most optimized code representations and runtime
machine state.
- Special considerations arise when debugging garbage collection, for
example the Inspector's dependence on the VM's meta-information
about classes, methods, etc., which are represented as ordinary
:doc:`Java objects <./Objects>` in the heap; garbage collection,
however,
routinely breaks the heap invariants that make those objects
accessible.
- Good debugging support is paramount for a VM intended for
experimentation and fast prototyping.
- The Maxine Inspector addreses these concerns, supporting
comprehensive inspection and interaction at all program
representation levels.
- Finally, these services must be available to developers in a wide
variety of contexts: examining a pre-execution
:doc:`boot image <./Boot-Image>`, examining and controlling a live VM
process (local or remote), and post-mortem examination of a VM core
dump.
Furthermore, the Inspector's design exploits the fact that it is implemented in the same language that the VM implements and is implemented in; this gives rise to many code reuse opportunities.
For example, the same mechanisms used by the VM's :doc:`boot image generator <./Boot-Image>`, which allow the creation of objects in the binary runtime format for a potentially different platform, can be used by the Inspector to examine binary runtime state for a potentially different platform than the Inspector's host.
Downloading and Building the Inspector
--------------------------------------
The Inspector source code is part of the Maxine VM repository.
It will :doc:`download and build <./build>` automatically with the rest of the Maxine code.
See also Inspector-specific issues on :doc:`various platforms <./build>`.
A Tour Through The Maxine Inspector
-----------------------------------
The best way to learn about the Inspector (and about many aspects of the Maxine VM) is to start up the Inspector on a simple VM session.
For a beginner's introduction, however, the following pages introduce specific aspects of the Inspector's operation, in some cases with short video segments.
The topics are threaded in a sequence so that you can navigate through them in order if you are new to the Inspector.
Boot Image Configuration
~~~~~~~~~~~~~~~~~~~~~~~~
A good introduction to some of the Maxine VM's architectural features is provided by the Inspector command via the Boot Image info entry on any `View <#view>`__ menu.
This produces an Inspector window displaying configuration parameters of the boot image being inspected.
The boot image and its configuration can be inspected with or without a running VM process.
`This short 2008 video <https://youtu.be/Ieoqp5TUUJ4>`__ demonstrates this view, although some evolution has taken place since then.
A more detailed description of the display appears below.
The Boot Image Inspector
^^^^^^^^^^^^^^^^^^^^^^^^
The boot image contains several groups of configuration parameters, each of which relates to some aspect of the Maxine implementation.
The Boot Image Inspector displays them in a simple tabular format, with entries in several general categories:
- *Identification* of the particular boot image build.
- Basic *build options*, e.g. ``DEBUG`` or ``PRODUCT``.
- *Target machine properties*: the model, instruction set, word size,
endianness, etc. for which code is compiled, both in the boot image
and at run time.
- *Operating System properties*.
- *Maxine schemes*: pluggable modules that implement specific functions
in the VM.
For example, the *grip scheme* implements low level memory
addressing, at which level garbage collection takes place; the *run
scheme* directs what happens at VM startup, which could be running a
standard Java program, as in the example, but could something else
specified at build time.
- Parameters describing the *boot heap*: a pre-populated heap segment
containing objects created at build time, in the same format as the
dynamic heap segments created at run time.
- Parameters describing the *boot code* region of memory, which
contains compiled code in the same format as the regions of compiled
code that are created by dynamic compilation and recompilation at
run time.
- *Code entry pointers*: specific addresses in the boot code region
(displayed symbolically by the inspector in the example) for
distinguished methods that will be called at VM startup.
- *Distinguished object pointers*: specific addresses in the boot heap
region for objects of importance at VM startup, for example the root
``ClassRegistry`` object (displayed symbolically by the inspector in
the example).
.. image:: images/Inspector-BootImage.jpg
As with many data displays in the Inspector, the items in the Value
column have additional useful behavior.
For example, most provide additional information about the displayed
value in a mouse-over "Tooltip" display that appears when the mouse
hovers over the display.
In simple cases, such as integers, the Tooltip might display the value
in another base.
For example the page size item displays in decimal by default, but the
hexadecimal value appears in the Tooltip.
Conversely, the boot heap size displays in hexadecimal by default, and
the decimal value appears in the Tooltip.
Any display item showing a memory value that could be interpreted as a pointer to a memory location exhibits much more complex behavior, described in more detail in `Memory Word Values <#memory-word-values>`__.
The Inspector investigates each of these values empirically to determine where such a value might point in the VM's current memory.
In the displayed example, the value of the parameter ``boot heap start`` was discovered to point at a heap object, presumably the first object in the region.
Although displayed in hexadecimal by default, the item is color coded green to reveal this fact, and an alternate display showing information about the object (for example the ``class registry`` pointer) might also appear by default.
Similarly, parameter named ``MaxineVM.run()`` was discovered to point to the compiled code for a specific method, in this case evidently the correct one; in the example, these are displayed symbolically by default.
These display items also exhibit dynamic behavior in response to various mouse actions.
For more detail, see `Memory Word Values <#memory-word-values>`__.
An optional `Memory Regions Column <#memory-regions>`__ is available by selecting the *View Options* entry from the `View <#view>`__ menu.
This setting is persistent, and it can also be set as a `User Preference <user-preferences>`__.
Memory Word Values
~~~~~~~~~~~~~~~~~~
Many Inspector views display values that represent the contents of a memory word in the VM.
Such words might contain primitive data values, but they also might contain addresses that point to other locations in the VM's memory such as heap objects and executable instructions.
We call an Inspector element that displays the contents of a memory word a *Memory Word Value*.
For example, in the Boot Image Inspector, shown here, of the parameter values in the lower part of the display are such Memory Word Values.
.. image:: images/Inspector-BootImage.jpg
Memory Word Values are among the most important aspects of the Inspector, and they appear in almost every kind of view.
They exhibit a variety of useful behaviors, described on this page, designed to make the Inspector as useful as possible.
Investigating memory references
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A Memory Word Value is often bound to a specific word location in the memory of a running VM.
After each VM execution cycle, the Inspector "refreshes" every Memory Word Value, which causes the value in each word to be from memory read again.
Each time this happens, the Inspector attempts to relate the value found to other information that is already known about the state of the VM.
In many cases the Inspector can determine by context that a particular word value ought to or might point to some specific kind of location.
In every case, however, the Inspector investigates the value of the word and determines empirically whether the value points to some known part of the VM state; this is essential for debugging the VM implementation, since those assumptions might not always hold.
Note that this investigation of memory word values can be suspended by turning off the persistent `User Preference <#user-preferences>`__ *Investigate memory references*.
This does not, however, prevent the value from being read from memory at the conclusion of every refresh cycle.
Color-coding and mouse behavior
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When a word value does not point to any known kind of location (for
example the parameter boot code end in the Boot Image Inspector), the
value is simply displayed in plain hexadecimal (alternate
interpretations, for example decimal, are available in a mouseover
`Tooltip <#tooltips>`__).
When it does point to contents of a known kind, the display exhibits complex visual and interactive behavior that reveals what is known about the location to which the value refers.
This list describes some of those behaviors:
- *Color*: The default display color of a Memory Word Value is black, but if something is learned about where the value points the following color code reveals the kind of data to which the value refers:
- *green*: points at a `Heap Object <#heap-objects>`__.
- *blue*: points at a method entry for compiled `Machine
Code <#machine-code>`__.
- *pale* blue: points into the interior of a method for compiled
`Machine Code <#machine-code>`__.
- *magenta*: points into `Thread Local Memory <#thread-locals>`__.
- *red*: points into memory not known to be in a
`Memory Region <#memory-regions>`__ allocated by the VM.
- *Numeric Display*: A word of bits can be interpreted as several different types of numeric values.
For example, floating point register values being displayed in the `Registers Inspector <#registers-inspector>`__ can be displayed in three different formats: hexadecimal, as a float value, and as a double float value.
As noted below, a mouse middle-click over such a Memory Word Value will cause it to cycle among its possible display states.
- *Symbolic Display*: Some values that point to known kinds of
information have two modes of display: numeric and symbolic.
The default mode depends usually on whether the Inspector assumes
from context that a particular value should point to something
known.
In the Boot Image display, the parameter ``boot heap start`` is not
assumed to point at anything in particular, but the Inspector has
discovered that it points at a heap object.
On the other hand, the parameter ``class registry`` is assumed to
point to a heap object, so the default display mode is symbolic.
As noted below, a mouse middle-click over such a Memory Word Value
will cause it to cycle among its possible display states.
- *Heap Object References*: The symbolic display of a heap object
reference (for example, the value of the ``class registry``
parameter)
begins with an integer ID for the object that is unique for the
duration of the inspection, followed by the type of the reference,
displayed as an unqualified class name.
A variant display appears for objects of Maxine's low-level
implementation types:
``<Maxine role>(<java entity for which the object plays this role>)``.
Examples of such roles include Class Actor, Dynamic Hub, and Static
Tuple.
When a heap object reference is being displayed in numeric mode,
symbolic information is among the extra information available as a
`Tooltip <#tooltips>`__, and a mouse left-click will create a new
Object Inspector on the object.
- *Machine Code References*: The symbolic display of a word pointing
at compiled machine code is displayed (for Java methods) as the
unqualified class name, followed by the method name, followed by
empty parentheses, followed by a compilation index in square
brackets.
The compilation index identifies which of the potentially multiple
compilations of the method contains the reference location.
When a machine code pointer is being displayed in numeric mode,
symbolic information is among the extra information available as a
`Tooltip <#tooltips>`__, and a mouse left-click will create a new
Method Inspector on the object
- *Left Mouse Button*: A mouse left-click over a Memory Word Value
creates an Inspector for what, if anything, is pointed to by the
value.
If the value is a heap object reference, it creates a new
`Object Inspector <#heap-objects>`__.
If the value points into machine code, it creates a new Method
Inspector displaying the disassembled `Machine
Code <#machine-code>`__.
- *Middle Mouse Button*: A mouse middle-click cycles among the
display
states of the Memory Word Value under the mouse cursor.
- *Right Mouse Button*: A mouse right-click over a word value causes
a
menu of commands to be displayed.
Some entries in the menu are universal, for example *Copy Word To
Clipboard*.
When display modes are available, the command *Toggle Display Mode*
performs the same function as a mouse middle-click.
Commands are available that create a
`Memory Inspector <#the-memory-inspector>`__ at the location
specified
by the word value.
Yet other commands are sensitive to the particular kind of
information pointed to by the value, for example commands
associated
with Java methods or with Constant Pool entries.
Tooltips
^^^^^^^^
A "tooltip" is a display of a small amount of text that pops up
temporarily when the mouse rolls over display element.
In the case of Word Value Labels, tooltips display several kinds of
useful information that complement the terse displayed text of the
element.
The duration of each tooltip's appearance can be controlled by the
`User Preference <#user-preferences>`__ *ToolTip dismiss*.
Most Word Value Labels in Inspector views appear in tables, which have a
"cell" on each row under each column, and in these tables there is a
strong convention for what tooltip text appears.
The first line of tooltip text usually identifies the particular row
under the cursor, and in particular the VM entity that is being
portrayed by that row in the table.
Examples include:
- ``Object header field "MISC"``
- ``Instruction 4 "mov"``
- ``Thread local "MUTATOR_STATE``
The remaining tooltip lines display additional information, possibly
redundant, about the cell under the cursor.
For example, a cell in the Value column of an
`Object Inspector <#heap-objects>`__ or
`Memory Inspector <#the-memory-inspector>`__ whose memory word contains a
``Reference``, displays both the address in hexadecimal and a short
description of the referred to object, whereas the table cell itself
displays only one of these at a time, depending on its display state.
Furthermore, that tooltip also describes the memory region into which
the ``Reference`` points, something that is otherwise visible only by
activating a separate column in the view.
Cells in a ``Name`` column add to the tooltip any of the short
"description" strings associated with some Maxine VM internal
entities.
For example, this string describes the purpose of a VM thread local, and
it appears with the tooltip over its name in the
`VM Thread Locals Inspector <#thread-locals>`__.
Cells in the ``Tag`` column of any memory-based Inspector view will
display tooltip text (following the line 1 descriptor) that describes
(a) the registers, if any, that point into the row's memory region, (b)
the watchpoints, if any, that are set in the row's memory region, and
(c) the watchpoint, if any, that is currently triggered on a location
(specified) in the memory region.
Some of this information is redundant, since a special cell border
reveals the presence of a watchpoint, a special icon and color reveals
the location of a triggered watchpoint, and the cell's text lists any
registers pointing into the region.
Some is not, however, for example the specific address information at
which a watchpoint trigger occurred; this information is otherwise only
visible in the `Watchpoints Inspector <#watchpoints>`__.
The specific kind of additional information that appears is quite
dependent on context: on the particular column (``Value`` or ``Address``),
on an expectation about the value (e.g. "should contain a Reference"),
and the actual value discovered in VM memory. This overall approach is
designed to offer:
- verbosity and redundancy for the beginner (and sometimes for the
pro), and
- additional information for the pro, information that can reduce
jumps to another view and reduce the number of columns visible
(which in turn frees visual space for other information).
Drag and drop
^^^^^^^^^^^^^
A Memory Word Value display can also act as the source of a Drag & Drop
operation.
If the value points into a known region of memory, dragging the value
away from the display and dropping it onto the Inspector's background
window will produce a `Memory Inspector <#the-memory-inspector>`__ whose
display begins at that address.
The Memory Inspector
~~~~~~~~~~~~~~~~~~~~
Most of the views provided by the Maxine Inspector display something
about the state of the VM that has been read from memory as raw bytes
and then been interpreted in useful terms, based on the Inspector's
embedded knowledge of the VM's design.
Many such views are described in subsequent sections.
Sometimes, however, it is important to display memory at a very low
level, without assumptions about content, and the Maxine Inspector
offers low-level views for this purpose.
default "Word" mode
^^^^^^^^^^^^^^^^^^^
An Inspection session can contain any number of Memory Inspectors.
The default behavior of a Memory Inspector is demonstrated by the
example to the right.
The specified range of memory being displayed appears in the window
header, along with the name of the allocated
`Memory Region <#memory-regions>`__ in which the first word lies.
The memory in the specified range appears, grouped by word, one word per
row, using the default columns that appear in the example:
- Tag column: a place where additional information about the memory
word can be displayed.
For example it displays the names of any registers in the currently
selected thread that point at the location.
The Tag column also highlights any word where a Watchpoints is
set.
Many Inspectors have a similar Tag column.
- Addr. column: the location of the first byte in the word, expressed
as a hexadecimal memory address.
- Offset column: the location of the word, specified as the number of
bytes offset (either positive or negative) from the current origin
of the Inspector (more about the origin follows below}.
- Value column: The contents of each word are read from the VM memory
each time the VM halts.
The values are displayed with numerous visual and interactive
behaviors that depend on the value and the context of their
appearance.
See `Memory Word Values <#memory-word-values>`__ for details.
- Region column: displays the name of
the `Memory Region <#memory-regions>`__, if any, into which the value
currently stored in the word points.
See `Memory Regions Column <#memory-regions>`__.
.. image:: images/Inspector-MemoryWord.jpg
A Memory Inspector can be created in several ways:
- The *Inspect memory at address...* entry in the
standard `Memory menu <#menus>`__ brings up a dialog in which a
starting address for a new Memory Inspector may be entered.
- The *Inspect this object's memory* entry in the Memory menu
appearing on any `Object Inspector <#heap-objects>`__.
- Clicking on the *Create cloned copy...* button in the tool bar of
any existing Memory Inspector; this creates a new Memory Inspector
whose location is identical to the original, but whose subsequent
behavior is independent of the original.
- Dragging any `Memory Word Value <#memory-word-values>`__ to the
Inspector's background; if the value can be interpreted as a memory
location known to be allocated, a new Memory Inspector will be
created started at that location.
- Dragging the display of any `Memory Region <#memory-regions>`__ name
(for example, any name displayed in
a `Memory Region Column <#memory-regions>`__) to the Inspector's
background; a new Memory Inspector will be created whose display
spans the entire region.
Note that the Memory Inspector depicted in this example is currently in
Word mode, as indicated by the pull-down selector in the Inspector's
tool bar.
In this mode the Back and Forward arrow buttons serve to relocate the
viewing region of the Memory Inspector forward or backward one word at a
time.
The operation of the arrow buttons in other modes (Object and Page
modes) is discussed in subsequent sections.
Navigation also takes place in response to the scroll bar and by
resizing the window.
origin
^^^^^^
Every Memory Inspector maintains a current *origin* at all times; this
is a word-aligned memory address from which the locations displayed in
the ``Offset`` column are computed.
When a Memory Inspector is created, the *origin* is set initially to the
first word of the memory being displayed, but the location of the origin
is thereafter unconstrained.
Commands in the Memory Inspector's View menu, or direct editing of the
``Origin`` field, allow the origin to be set elsewhere.
.. image:: images/Inspector-MemoryWordOrigin.jpg
In this example, the displayed memory region is the same as the previous
example, but the *origin* has been set to a location in the middle of
the displayed region.
This example also shows the graphical separators that are applied by the
Memory Inspector whenever it discovers `Heap Object <#heap-objects>`__
boundaries in VM memory.
"Object" mode
^^^^^^^^^^^^^
Navigation in the Memory Inspector is modulated by the mode currently
selected via a pull-down selector in the Inspector's tool bar, located
between the Back and Forward arrow buttons.
.. image:: images/Inspector-MemoryObject.jpg
In this example the mode is set to Object, which causes the ``Back`` and
``Forward`` buttons to move backward and forward one object at a time,
assuming any objects can be located.
Each Object-mode move resets the Inspector's origin to the first word of
the object's representation and scrolls until that position is in the
first viewing position.
These moves do not change the size of the region being displayed, nor do
they cause the window to resize around the current object being
displayed.
"Page" mode
^^^^^^^^^^^
Navigation in the Memory Inspector is modulated by the mode currently
selected via a pull-down selector in the Inspector's tool bar, located
between the ``Back`` and ``Forward`` arrow buttons.
.. image:: images/Inspector-MemoryPage.jpg
In this example the mode is set to ``Page``, which can be very helpful
when working on page-based mechanisms in the VM, for example garbage
collection.
In this mode the size of the region is constrained to equal the page
size of the platform, and the origin is constrained to location at page
boundaries.
Navigation via the ``Back`` and ``Forward`` buttons relocates the viewing
region by one page per click.
Manually changing either the ``Origin`` or ``Words`` size fields causes the
mode to revert to Word.
View options
^^^^^^^^^^^^
The Memory Inspector provides a number of options for displaying word
contents under different interpretations, available via the *View Options* entry in the Inspector's *View* menu.
The options dialog can also be invoked by clicking on the rightmost
button in the tool bar.
In the example below, all optional columns are displayed. Each column
displays the memory contents under a different interpretation: as Bytes,
as Chars, as Unicode, as a single-precision Float, and as a
Double-precision float.
.. image:: images/Inspector-MemoryOptions.jpg
The Memory Bytes Inspector
^^^^^^^^^^^^^^^^^^^^^^^^^^
There are times when low-level memory inspection in terms of words, the
only mode supported by the standard
`Memory Inspector <#default-%22word%22-mode>`__ described above, is not
flexible enough for the task at hand.
In these situations the Memory Bytes Inspector, shown in the example to
the right, offers a much more flexible alternative.
.. image:: images/Inspector-MemoryBytes.jpg
This Inspector can be configured to display memory at any location
(address, length), and can display memory in any grouping of bytes.
In the special case where bytes appear in groups of 1, as in the
example, each byte is also interpreted as an ASCII character. In the
special case where bytes appear in groups of 2, each group is also
interpreted as a UNICODE character.
In the special case where the address of a byte group is determined
empirically to be a valid reference to either a heap object or code,
this information can be displayed symbolically.
In the example at the right, the Memory Bytes Inspector has observed
that the address of the first group points to an object and has color
coded the display to indicate that.
See `Memory Word Values <#memory-word-values>`__ for more details.
A Memory Bytes Inspector can be created in several ways:
- The *Inspect memory bytes at address...* entry in the standard
Memory menu brings up a dialog in which a starting address for a new
Memory Bytes Inspector may be entered.
- The *Inspect memory at Origin as bytes* entry in the View menu
appearing on any Memory Inspector.
- A right mouse-click over the Tag column in most memory-based views
will produce a popup menu, one entry of which is Inspect this memory
as bytes.
Memory Regions
~~~~~~~~~~~~~~
The Maxine VM allocates memory in regions dedicated to various
subsystems.
These regions are given names for the purposes of inspection, and the
Inspector provides two mechanisms for observing this aspect of of the
VM's runtime state:
`the Memory Regions Inspector <#the-memory-regions-inspector>`__ and
`the Memory Regions Column <#the-memory-regions-column>`__, which can be
optionally displayed with many of the other Inspector Views.
The Memory Regions Inspector
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The Memory Regions Inspector displays a tabular summary of every
currently allocated region of memory in the running Maxine VM, with the
following columns displayed by default:
- *Tag*: a place where additional information about the memory region
can be displayed.
In the example to the right the Tag entry in the second row notes
that register R14 currently points into the region
``Thread-2 Locals``.
The Tag column also highlights any memory region where one or
more `Watchpoints <#watchpoints>`__ are set.
Many Inspectors have a similar Tag column.
- *Name*: a human readable name that describes its purpose.
In the example the two regions named Heap-Boot and Heap-Code are
preconfigured as part of the binary boot image
(see `Boot Image Inspector <#boot-image-configuration>`__), each in
the
runtime format of the dynamic heap and code regions respectively.
Additional regions are allocated dynamically for code compiled at
run time, for example the region named Code-Runtime.
Specific heap implementation allocate memory according to a garbage
collection scheme, for example the Heap-From and Heap-To regions
allocated by a semi-space collector.
Finally, a region of memory for the VM's internal
`Thread Local Storage <#thread-locals>`__ is allocated for each
thread,
named after the particular thread's ID.
- *Start*, *End*: location of the region, expressed as hexadecimal
memory addresses.
- *Size*: number of bytes contained in the memory region, expressed by
default in headecimal, but with additional formats available in
mouseover Tooltip text.
- *Alloc*: the percentage of the region that has actually been used by
the particular subsystem owning the region, if this can be
determined.
.. image:: images/Inspector-MemoryRegions.jpg
In the special case where a *Start* or *End* address is determined
empirically by the Inspector to be a valid reference to known kinds of
information, this information can be displayed symbolically.
In the displayed example, the addresses colored green have been
determined to point at heap objects, and the addresses colored magenta
have been deteremined to point into thread local storage.
Additional behaviors are available at such address display: mouseover
Tooltips, mouse left-click, and mouse right-click (all of which are
described in more detail in the field values section for
`Heap Objects <#heap-objects>`__).
Dragging a hexadecimal address from the *Start* or *End* columns onto
the Inspector background causes a
`Memory Inspector <#the-memory-inspector>`__ to be created starting at that
location and having a small default display span.
Dragging a name from the *Name* column causes a Memory Inspector to be
created whose span is the entire extent of the region.
The Memory Regions Column
^^^^^^^^^^^^^^^^^^^^^^^^^
Most Inspector views offer multiple columns of display information, only
a few of which may be visible by default.
The View Options menu item, available in the standard
`View menu <#menus>`__, allows user selections of visible columns.
This setting is persistent, and it can also be set as a
`User Preference <#user-preferences>`__.
.. image:: images/Inspector-MemoryRegionColumn.jpg
Every Inspector that display memory values of any kind offers an
optional column with the title *Region*.
In the example to the right, the `Registers Inspector <#registers>`__ is
shown with the Memory Regions Column visible.
The Memory Regions Column display is based on a Memory Word Value
associated with the particular row.
If the Word Value is determined to point to a valid location somewere in
the runtime state of the VM, the name of the memory region into which it
points is displayed.
If the Word Value does not point into a valid memory location, or if it
is a different kind of value display, then the The Memory Regions Column
is blank.
In the example several of the Word Values point to heap objects: some to
objects in the Boot Heap memory region
(see `Boot Image Inspector <#boot-image-configuration>`__), and some to the
dynamic heap region Heap-To allocated by the
`semi-space garbage collector <http://en.wikipedia.org/wiki/Cheney%27s_algorithm#Semispace>`__,
one of several implemented in the Maxine VM.
Some values point into the VM's allocation for particular
threads.
Finally, the RIP register, which is assumed to point into executable
code, does indeed point into a compiled method, as shown by the display
in symbolic mode.
Dragging a hexadecimal address from the Value column onto the Inspector
background causes a Memory Inspector to be created starting at that
location and having a small default display span.
Dragging a name from the Region column causes a Memory Inspector to be
created whose span is the entire extent of the region.
Heap Objects
~~~~~~~~~~~~
A Maxine Object Inspector displays the contents of a single heap object
as a sequence of name/value tuples with additional display
options.
Variant object representations in the VM are displayed with slightly
different kinds of Object Inspectors: tuples (ordinary objects), arrays,
and a special hybrid object used in the VM implementation that cannot be
expressed as a Java type.
Furthermore, certain common types can be displayed in multiple modes,
for example the contents of a ``char[]`` might alternately be displayed as
a string.
View a short demo `here <https://youtu.be/kMo1-zBQh28>`__, or see below for
examples and discussion of the heap object inspector's behavior.
Note that the design of Heap Object Inspectors has changed since the
demo video.
There are many additional display features and options.
Inspecting tuple heap objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ordinary objects are referred to as Tuples in the Maxine VM
implementation The first example window at the right displays the
contents of a simple object of type
``com.sun.max.vm.heap.BootHeapRegion``.
The object is visualized as a simple list of *Field*/*Value* tuples.
In this example, all other view options for the objects are turned off.
.. image:: images/Inspector-TupleHeapObject.jpg
A basic Heap Object Inspector such as this one displays the following
elements of a tuple:
- *Title Bar*: The window frame displays a compact string identifying
the object: absolute address in memory, an integer ID for the object
that is unique for the duration of the inspection, followed by the
type of the object (as an unqualified class name) and the
`Memory Region <#memory-regions>`__ in which it resides.
- *Menu Bar*: The `Standard Menus <#menus>`__ relevant to the Object
Inspector.
- *Tag* column: The Inspector annotates each field with
meta-information that may relate to other aspects of VM state or to
the interactive state of the inspection session.
For example, an annotation lists the names of all machine
`Registers <#registers>`__ in the currently selected thread
that point at the location represented by the row.
A graphical annotations marks the locations of active
`Watchpoints <#watchpoints>`__ for debugging.
A mouse double-left-click in the Tag column toggles on and off the
watchpoint at the specified location.
A mouse right-click in the Tag column displays a menu of actions
relevant to the specific memory location.
- *Field* column: All fields in the object, local or inherited, appear
one per row, with the unqualified field name appearing in this
column.
A mouseover Tooltip reveals the type of the field and the class in
which it is declared; both names in the ToolTip are fully qualified.
- *Value* column: The contents of object fields are read from the VM
memory each time the VM halts.
The values are displayed with numerous visual and interactive
behaviors that depend on the value and the context of their
appearance.
See `Memory Word Values <#memory-word-values>`__ for details.
Ordinary Java object, such as the one in this example, are represented
in the Maxine VM heap as Tuples.
There are two other general kinds of objects in the Maxine heap, for
which Object Inspector behavior differs somewhat, as described below:
`Arrays <#array-objectss>`__, corresponding to ordinary Java arrays, and
`Hybrids <#hybrid-objects>`__, types specialized for the Maxine VM
implementation that do not correspond to any Java type.
Object Inspector view options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
View options are available available by selecting the View Options entry
from the View menu.
A dialog permits the request for additional kinds of information, either
for the current Object Inspector only or for all subsequently created
Object Inspectors.
The setting for all subsequently created Object Inspectors is
persistent, and it can also be set via the Preferences action
(see `User Preferences <#user-preferences>`__).
The following example displays a heap object of type BootHeapRegion with
all view options turned on.
.. image:: images/InspectorTupleHeapObjectOptions.jpg
This example displays the same object as the previous example, but with
every kind of optional view information enabled.
These are listed below, not including the basic display features already
described above.
- *Object header*: The Maxine VM implementation of heap objects adds
an additional two or three fields in the object representation's
header.
In the case of simple objects such as this one, the two fields
include a reference to the Maxine information (represented as Java
objects) concerning the class of the object, followed by a word of
bit fields used for a variety of purposes, including locking.
A third, when present, specifies the length of the array part of an
object (see `Array Objects <#array-objects>`__)
and `Hybrid Objects <#hybrid-objects>`__ below).
- *Addr.* column: displays the absolute current location of the field
in VM memory, which may change when the heap is managing by a
copying garbage collector.
A mouseover Tooltip over this column displays the field's offset
from the beginning of the object, the same information displayed in
the Offset column.
A mouse right-click over an address produces a menu with standard
commands for copying the value onto the clipboard and creating a
`Memory Inspector <#the-memory-inspector>`__ at this location.
- *Offset* column: displays the field's location relative to the
origin of the object, where the object layout is determined by a
Maxine scheme.
In this example, the object layout assigns the origin to memory
location 0 in the representation of the object.
A moueover Tooltip displays the field's absolute memory location,
the same information displayed in the optional Addr.
column.
A mouse right-click over this column produces a menu with standard
commands for copying the value onto the clipboard and creating a
`Memory Inspector <#the-memory-inspector>`__ at this location.
- *Type* column: displays the Java language type of the value,
expressed as either Java primitive type names or unqualified Java
class names.
Mouseover Tooptips display symbolic information about the Maxine
implementation of the type.
A mouse right-click produces a menu of commands for inspecting Java
objects related to the Maxine implementation of the type.
- *Region* column: displays the name of the
`Memory Region <#memory-regions>`__, if any, into which the value
currently stored in the field points.
See `Memory Regions Column <#memory-regions>`__.
Dragging a hexadecimal address from the Addr.
column onto the Inspector background causes a
`Memory Inspector <#the-memory-inspector>`__ to be created starting at
that location and having a small default display span.
Dragging a name from the Region column causes a
`Memory Inspector <#the-memory-inspector>`__ to be created whose span is
the entire extent of the region.
Arrays
^^^^^^
The Object Inspector displays slightly different information for objects
that the VM uses to represent Java arrays, as shown in the example.
This Inspector displays an integer array of length 11; a scroll bar
would appear when array length exceeds the size of the view window.
.. image:: images/InspectorArrayHeapObject.jpg
Array values are displayed exactly as for field values in ordinary tuple
objects: as `Memory Word Values <#memory-word-values>`__.
In the example, the values are references to objects of type
``MethodActor``.
This display differs from an ordinary
`Tuple Object Inspector <#inspecting-tuple-heap-objects>`__ in two ways.
First, the object header contains a third field that holds the length of
the array.
Second, the Field column identifies the index of each array element.
A mouse double-left-click in the Tag column sets a watchpoint at the
specified array element.
Other than the object header, all view options are turned off in this
display.
Standard view options are available for *Addr.*, *Offset*, *Type*, and
*Region* column.
These options are similar to the View Options available for ordinary
tuple objects and are available under the View Options entry in the
`View menu <#menus>`__.
An additional view option is available for array objects: suppressing
the display of ``null`` elements, where the definition of ``null`` depends
on the particular element type.
This can greatly improve visualization of sparsely populated arrays.
Hybrid objects
^^^^^^^^^^^^^^
For performance reasons, the Maxine VM stores much of its class-specific
implementation metadata in a special kind of heap object that has no
counterpart in the Java language.
These objects are *hybrids*: they contain fields, as with an ordinary
tuple object, but they also contain arrays dedicated to implementation
data that must be efficiently accessed when examining the representation
of an object.
.. image:: images/InspectorHybridHeapObject.jpg
Each ordinary object's header, as shown in earlier examples above,
contains a pointer to the object's *Hub*, which is implemented in the heap
as a Maxine hybrid object.
The example shown to the right is a hybrid object representing the
*Dynamic Hub* for objects of type ``java.lang.String``.
Every ``String`` object in the heap contains a pointer to this hub.
Each class at runtime also contains static values, represented as an
object of the special type StaticTuple, whose metadata is contained in
an object of type StaticHub, also represented as a hybrid object.
Note in passing the following circularity: the Hub pointer of a
``DynamicHub`` points to the ``DynamicHub`` for class ``DynamicHub``.
Reflecting the complexity of hybrid objects, the Object Inspector
displays a hybrid as a collection of segments, each with different kinds
of information.
- As with `Array Objects <#array-objects>`__, hybrids contain a word in
the header that contains the total length of the array part of the
object.
- As with `Tuple Objects <#inspecting-tuple-heap-objects>`__, hybrids
contain named fields, displayed in the fields segment of the Object
Inspector.
- The array segment of a hybrid us used to represent four kinds of
information, and the Object Inspector displays each separately:
``vTable``, ``iTable``, ``mTable``, and ``Reference Map``.
Each array segment behaves as for `Array Objects <#array-objects>`__.
- Each array segment is individually scrollable, and each can be
either displayed or hidden by using checkboxes at the beginning of
the Object Inspector.
Specialized Object Inspectors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The Object Inspector can be specialized by adding alternate displays for
heap objects of particular types.
Several are currently in place, most of which display a textual summary
of the object's contents.
In two examples shown, a char array is shown to have such a specialized
alternate configured, evident by the appearance of window tabs that
select the display.
The standard array display appears in the upper example, while the
textual summary appears in the lower example.
.. image:: images/Inspector-ObjectCharArray1.jpg
.. image:: images/Inspector-ObjectCharArray2.jpg
Object view canonicalization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In ordinary operation, the Inspector creates at most one Object
Inspector per unique object in the VM's heap.
A user request to view an object, for example by clicking on a value
field that points at an object (see [Memory Word Values\|Inspector-Memory
Word Values), will cause a new Object Inspector to be created only if
one does not already exist; if one does exist, it is simply brought
forward and into full view.
The determination is made by comparing the memory location of the two
potentially identical objects.
In some situations, however, especially during garbage collection, the
Inspector may not be able to make this determination identity
correctly.
For example, a relocating garbage collector may create a copy of an
object's representation, and this relationship may not be detectable
immediately.
The Inspector is designed to sort this out as much as possible, most
importantly by stopping the VM at the conclusion of each GC cycle and
reviewing reviewing for duplications its table of VM heap objects.
This is work in progress, and the Inspector may not always get identity
sorted out correctly in every situation for every implementation of
garbage collection.
Machine Code
~~~~~~~~~~~~
A Maxine Method Inspector displays code associated with a method body in
several ways.
Here we show how machine code can be disassembled and displayed with
useful interactive behavior.
View a short demo `here <https://youtu.be/zkcPPkO7N5o>`__, or see below for
a discussion and screen snapshots of the Machine Code Inspector
Note that the design of Method Inspectors has changed somewhat since the
demo video.
Method Inspector with machine code
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The first example shows a Method Inspector displaying the disassembled
machine code for the Java method ``com.sun.max.vm.MaxineVM.run()``, which
is called by the VM at the conclusion of the startup sequence.
Display features include:
- A *tab* that distinguishes the method inspector from others in a
"tabbed window";
- A *window header* that identifies the method in detail (which
information is also available on the tab as a mouseover Tooltip);
- A *suffix* to the name that identifies the specific compilation of
the
method; in the example the suffix "0" identifies the machine code as
the first entry in the method's compilation history;
- A number of *command buttons* for Debugging;
- A dialog for setting *view options*, available from the *View...*
button, in which specific display columns can be selected or
deselected (the next example shows all columns);
- A *Tag* column that displays markers related to Debugging, such as
the triangular symbol for the current Instruction Pointer in the
first row of the example;
- A *Label* column that displays symbolic labels generated by the
disassembler; information about the actual location in memory is
available as a mouseover Tooltip in this column, and a menu of
commands related memory locations is available via mouse right-click
over this column;
- An *Instruction* column displaying mnemonic machine operations, as
configured for the target instruction set; and
- An *Operands* column displaying mnemonics for machine code operands,
as configured for the platform instruction set; in the special case
where memory addresses appear in machine code operands, the
inspector empirically determines whether the address points at a
heap object or code entry, and if so, displays that information
symbolically; additional display and interactive options are
available over such references, as described in the Field Values
section in `Heap Objects <#heap-objects>`__.
.. image:: images/Inspector-MachineCode1.jpg
Optional display columns
^^^^^^^^^^^^^^^^^^^^^^^^
The second example window shows the same method inspection as the first,