MACHINE.txt 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #####
  2. #
  3. # TAGGING
  4. #
  5. We're working on a machine with 64 bit words that address bytes.
  6. * 64 bits = 2^3 = 8 bytes
  7. If we ensure our pointers are 8 byte aligned then their
  8. addresses all end in 000. We can use these 3 bits as a tag.
  9. pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppttt
  10. not every object is a pointer though, we have immediates:
  11. (A) bool, nil, symbol, char
  12. (B) number
  13. (We don't need the symbol object to be a pointer, an index into the
  14. symbol table is fine since displaying symbol names isn't a speed
  15. priority.)
  16. In the case of immediates we can smush several into one ttt tag
  17. and use some more bits ss to distinguish them:
  18. iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiissttt
  19. We also make vectors a special type of a record, to save a tag.
  20. * The special 'all zeros' value of #f can be used with jnz.
  21. * We can save the 'nil' value in a register for fast comparison.
  22. * Char is large enough to hold a unicode code point.
  23. type obj data
  24. --------------------------------------
  25. bool #f .....0[00][000]
  26. bool #t .....1[00][000]
  27. nil nil .....0[01][000]
  28. symbol [--32 bits--]...[10][000]
  29. char [--32 bits--]...[11][000]
  30. number [-------61 bits------][001]
  31. cons *[010]
  32. closure *[011]
  33. string *[100]
  34. vector + record *[101]
  35. io port [110]
  36. gc-redirect marker *[111]
  37. #####
  38. #
  39. # LAYOUT
  40. #
  41. All objects will point into the heap except strings may be stored
  42. elsewhere (e.g. constant strings stored in the data section).
  43. ptr heap
  44. -------------------------------------------------------------
  45. cons --> [ car ][ cdr ]
  46. closure --> [ label ][ length ][ env1 ][ env2 ]...
  47. string --> <string-data>
  48. vec/rec --> [ tag/len ][ field-1 ][ field 2 ][ field-3 ]...
  49. gc-mark --> <an objects new place in the other-heap>
  50. #####
  51. #
  52. # CALLING CONVENTION
  53. #
  54. The calling convention is like this:
  55. - Caller enter:
  56. push return-address
  57. push base-pointer
  58. push arg-1
  59. push arg-2
  60. ...
  61. push arg-n
  62. set base-pointer to stack-pointer
  63. jump func
  64. this sets the stack up like:
  65. [ret addr][saved bp][arg-1][arg-2]..[arg-n]
  66. ^ new bp
  67. - Callee enter:
  68. increase the stack size to make space for its own temps
  69. - Callee exit:
  70. we need to throw away all the temps and args. can do this in one step.
  71. then restore the previous base pointer
  72. and ret
  73. mov rsp, rbp
  74. pop rbp
  75. ret
  76. - Caller exit:
  77. The caller has no resposibility.
  78. All the args it pushed on the stack have been consumed, base pointer restored.
  79. #####
  80. #
  81. # STACK
  82. #
  83. The stack layout needs to support the following:
  84. * The garbage collector needs to scan through to as a gc root.
  85. For this to be possible it has to be able to skip past non scheme objects like labels.
  86. * We need to be able to produce stack traces based on the labels.
  87. * Support variable number of arguments to function calls
  88. . previous stack .
  89. : frame :
  90. +----------------+
  91. | return address |
  92. +----------------+
  93. | saved base ptr |
  94. +----------------+
  95. | arg 1 | <- base pointer
  96. +----------------+
  97. | arg 2 |
  98. +----------------+
  99. : :
  100. : :
  101. +----------------+
  102. | arg n |
  103. +----------------+
  104. | tmp 1 |
  105. +----------------+
  106. | tmp 2 |
  107. +----------------+
  108. : :
  109. : :
  110. +----------------+
  111. | tmp n |
  112. +----------------+
  113. : scheme objects : (this will usually just
  114. : saved by the : be the env register)
  115. : callee :
  116. +----------------+
  117. . <-- stack pointer
  118. args will be referenced relative to base pointer
  119. temporaries will be referenced relative to stack pointer
  120. this allows us to support variadic functions!
  121. in the case of a variadic function the callee must cons up the rest list. The reason for this is it allows fast function calls in the non-variadic case.