libv8-sgonyea 3.3.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (500) hide show
  1. data/.gitignore +8 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +4 -0
  4. data/README.md +76 -0
  5. data/Rakefile +113 -0
  6. data/ext/libv8/extconf.rb +28 -0
  7. data/lib/libv8.rb +15 -0
  8. data/lib/libv8/Makefile +30 -0
  9. data/lib/libv8/detect_cpu.rb +27 -0
  10. data/lib/libv8/fpic-on-linux-amd64.patch +13 -0
  11. data/lib/libv8/v8/.gitignore +35 -0
  12. data/lib/libv8/v8/AUTHORS +44 -0
  13. data/lib/libv8/v8/ChangeLog +2839 -0
  14. data/lib/libv8/v8/LICENSE +52 -0
  15. data/lib/libv8/v8/LICENSE.strongtalk +29 -0
  16. data/lib/libv8/v8/LICENSE.v8 +26 -0
  17. data/lib/libv8/v8/LICENSE.valgrind +45 -0
  18. data/lib/libv8/v8/SConstruct +1478 -0
  19. data/lib/libv8/v8/build/README.txt +49 -0
  20. data/lib/libv8/v8/build/all.gyp +18 -0
  21. data/lib/libv8/v8/build/armu.gypi +32 -0
  22. data/lib/libv8/v8/build/common.gypi +144 -0
  23. data/lib/libv8/v8/build/gyp_v8 +145 -0
  24. data/lib/libv8/v8/include/v8-debug.h +395 -0
  25. data/lib/libv8/v8/include/v8-preparser.h +117 -0
  26. data/lib/libv8/v8/include/v8-profiler.h +505 -0
  27. data/lib/libv8/v8/include/v8-testing.h +104 -0
  28. data/lib/libv8/v8/include/v8.h +4124 -0
  29. data/lib/libv8/v8/include/v8stdint.h +53 -0
  30. data/lib/libv8/v8/preparser/SConscript +38 -0
  31. data/lib/libv8/v8/preparser/preparser-process.cc +379 -0
  32. data/lib/libv8/v8/src/SConscript +368 -0
  33. data/lib/libv8/v8/src/accessors.cc +767 -0
  34. data/lib/libv8/v8/src/accessors.h +123 -0
  35. data/lib/libv8/v8/src/allocation-inl.h +49 -0
  36. data/lib/libv8/v8/src/allocation.cc +122 -0
  37. data/lib/libv8/v8/src/allocation.h +143 -0
  38. data/lib/libv8/v8/src/api.cc +5845 -0
  39. data/lib/libv8/v8/src/api.h +574 -0
  40. data/lib/libv8/v8/src/apinatives.js +110 -0
  41. data/lib/libv8/v8/src/apiutils.h +73 -0
  42. data/lib/libv8/v8/src/arguments.h +118 -0
  43. data/lib/libv8/v8/src/arm/assembler-arm-inl.h +353 -0
  44. data/lib/libv8/v8/src/arm/assembler-arm.cc +2661 -0
  45. data/lib/libv8/v8/src/arm/assembler-arm.h +1375 -0
  46. data/lib/libv8/v8/src/arm/builtins-arm.cc +1658 -0
  47. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +6398 -0
  48. data/lib/libv8/v8/src/arm/code-stubs-arm.h +673 -0
  49. data/lib/libv8/v8/src/arm/codegen-arm.cc +52 -0
  50. data/lib/libv8/v8/src/arm/codegen-arm.h +91 -0
  51. data/lib/libv8/v8/src/arm/constants-arm.cc +152 -0
  52. data/lib/libv8/v8/src/arm/constants-arm.h +775 -0
  53. data/lib/libv8/v8/src/arm/cpu-arm.cc +120 -0
  54. data/lib/libv8/v8/src/arm/debug-arm.cc +317 -0
  55. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +754 -0
  56. data/lib/libv8/v8/src/arm/disasm-arm.cc +1506 -0
  57. data/lib/libv8/v8/src/arm/frames-arm.cc +45 -0
  58. data/lib/libv8/v8/src/arm/frames-arm.h +168 -0
  59. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +4375 -0
  60. data/lib/libv8/v8/src/arm/ic-arm.cc +1562 -0
  61. data/lib/libv8/v8/src/arm/lithium-arm.cc +2206 -0
  62. data/lib/libv8/v8/src/arm/lithium-arm.h +2348 -0
  63. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +4526 -0
  64. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +403 -0
  65. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +305 -0
  66. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.h +84 -0
  67. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +3163 -0
  68. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +1126 -0
  69. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +1287 -0
  70. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +253 -0
  71. data/lib/libv8/v8/src/arm/simulator-arm.cc +3424 -0
  72. data/lib/libv8/v8/src/arm/simulator-arm.h +431 -0
  73. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +4243 -0
  74. data/lib/libv8/v8/src/array.js +1366 -0
  75. data/lib/libv8/v8/src/assembler.cc +1207 -0
  76. data/lib/libv8/v8/src/assembler.h +858 -0
  77. data/lib/libv8/v8/src/ast-inl.h +112 -0
  78. data/lib/libv8/v8/src/ast.cc +1146 -0
  79. data/lib/libv8/v8/src/ast.h +2188 -0
  80. data/lib/libv8/v8/src/atomicops.h +167 -0
  81. data/lib/libv8/v8/src/atomicops_internals_arm_gcc.h +145 -0
  82. data/lib/libv8/v8/src/atomicops_internals_mips_gcc.h +169 -0
  83. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.cc +133 -0
  84. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.h +287 -0
  85. data/lib/libv8/v8/src/atomicops_internals_x86_macosx.h +301 -0
  86. data/lib/libv8/v8/src/atomicops_internals_x86_msvc.h +203 -0
  87. data/lib/libv8/v8/src/bignum-dtoa.cc +655 -0
  88. data/lib/libv8/v8/src/bignum-dtoa.h +81 -0
  89. data/lib/libv8/v8/src/bignum.cc +768 -0
  90. data/lib/libv8/v8/src/bignum.h +140 -0
  91. data/lib/libv8/v8/src/bootstrapper.cc +2184 -0
  92. data/lib/libv8/v8/src/bootstrapper.h +188 -0
  93. data/lib/libv8/v8/src/builtins.cc +1707 -0
  94. data/lib/libv8/v8/src/builtins.h +371 -0
  95. data/lib/libv8/v8/src/bytecodes-irregexp.h +105 -0
  96. data/lib/libv8/v8/src/cached-powers.cc +177 -0
  97. data/lib/libv8/v8/src/cached-powers.h +65 -0
  98. data/lib/libv8/v8/src/char-predicates-inl.h +94 -0
  99. data/lib/libv8/v8/src/char-predicates.h +67 -0
  100. data/lib/libv8/v8/src/checks.cc +110 -0
  101. data/lib/libv8/v8/src/checks.h +296 -0
  102. data/lib/libv8/v8/src/circular-queue-inl.h +53 -0
  103. data/lib/libv8/v8/src/circular-queue.cc +122 -0
  104. data/lib/libv8/v8/src/circular-queue.h +103 -0
  105. data/lib/libv8/v8/src/code-stubs.cc +267 -0
  106. data/lib/libv8/v8/src/code-stubs.h +1011 -0
  107. data/lib/libv8/v8/src/code.h +70 -0
  108. data/lib/libv8/v8/src/codegen.cc +231 -0
  109. data/lib/libv8/v8/src/codegen.h +84 -0
  110. data/lib/libv8/v8/src/compilation-cache.cc +540 -0
  111. data/lib/libv8/v8/src/compilation-cache.h +287 -0
  112. data/lib/libv8/v8/src/compiler.cc +786 -0
  113. data/lib/libv8/v8/src/compiler.h +312 -0
  114. data/lib/libv8/v8/src/contexts.cc +347 -0
  115. data/lib/libv8/v8/src/contexts.h +391 -0
  116. data/lib/libv8/v8/src/conversions-inl.h +106 -0
  117. data/lib/libv8/v8/src/conversions.cc +1131 -0
  118. data/lib/libv8/v8/src/conversions.h +135 -0
  119. data/lib/libv8/v8/src/counters.cc +93 -0
  120. data/lib/libv8/v8/src/counters.h +254 -0
  121. data/lib/libv8/v8/src/cpu-profiler-inl.h +101 -0
  122. data/lib/libv8/v8/src/cpu-profiler.cc +609 -0
  123. data/lib/libv8/v8/src/cpu-profiler.h +302 -0
  124. data/lib/libv8/v8/src/cpu.h +69 -0
  125. data/lib/libv8/v8/src/d8-debug.cc +367 -0
  126. data/lib/libv8/v8/src/d8-debug.h +158 -0
  127. data/lib/libv8/v8/src/d8-posix.cc +695 -0
  128. data/lib/libv8/v8/src/d8-readline.cc +130 -0
  129. data/lib/libv8/v8/src/d8-windows.cc +42 -0
  130. data/lib/libv8/v8/src/d8.cc +803 -0
  131. data/lib/libv8/v8/src/d8.gyp +91 -0
  132. data/lib/libv8/v8/src/d8.h +235 -0
  133. data/lib/libv8/v8/src/d8.js +2798 -0
  134. data/lib/libv8/v8/src/data-flow.cc +66 -0
  135. data/lib/libv8/v8/src/data-flow.h +205 -0
  136. data/lib/libv8/v8/src/date.js +1103 -0
  137. data/lib/libv8/v8/src/dateparser-inl.h +127 -0
  138. data/lib/libv8/v8/src/dateparser.cc +178 -0
  139. data/lib/libv8/v8/src/dateparser.h +266 -0
  140. data/lib/libv8/v8/src/debug-agent.cc +447 -0
  141. data/lib/libv8/v8/src/debug-agent.h +129 -0
  142. data/lib/libv8/v8/src/debug-debugger.js +2569 -0
  143. data/lib/libv8/v8/src/debug.cc +3165 -0
  144. data/lib/libv8/v8/src/debug.h +1057 -0
  145. data/lib/libv8/v8/src/deoptimizer.cc +1256 -0
  146. data/lib/libv8/v8/src/deoptimizer.h +602 -0
  147. data/lib/libv8/v8/src/disasm.h +80 -0
  148. data/lib/libv8/v8/src/disassembler.cc +343 -0
  149. data/lib/libv8/v8/src/disassembler.h +58 -0
  150. data/lib/libv8/v8/src/diy-fp.cc +58 -0
  151. data/lib/libv8/v8/src/diy-fp.h +117 -0
  152. data/lib/libv8/v8/src/double.h +238 -0
  153. data/lib/libv8/v8/src/dtoa.cc +103 -0
  154. data/lib/libv8/v8/src/dtoa.h +85 -0
  155. data/lib/libv8/v8/src/execution.cc +849 -0
  156. data/lib/libv8/v8/src/execution.h +297 -0
  157. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +250 -0
  158. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +89 -0
  159. data/lib/libv8/v8/src/extensions/experimental/collator.cc +218 -0
  160. data/lib/libv8/v8/src/extensions/experimental/collator.h +69 -0
  161. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +94 -0
  162. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +78 -0
  163. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +54 -0
  164. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +112 -0
  165. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +60 -0
  166. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +43 -0
  167. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +49 -0
  168. data/lib/libv8/v8/src/extensions/experimental/i18n.js +180 -0
  169. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +251 -0
  170. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +95 -0
  171. data/lib/libv8/v8/src/extensions/externalize-string-extension.cc +141 -0
  172. data/lib/libv8/v8/src/extensions/externalize-string-extension.h +50 -0
  173. data/lib/libv8/v8/src/extensions/gc-extension.cc +58 -0
  174. data/lib/libv8/v8/src/extensions/gc-extension.h +49 -0
  175. data/lib/libv8/v8/src/factory.cc +1222 -0
  176. data/lib/libv8/v8/src/factory.h +442 -0
  177. data/lib/libv8/v8/src/fast-dtoa.cc +736 -0
  178. data/lib/libv8/v8/src/fast-dtoa.h +83 -0
  179. data/lib/libv8/v8/src/fixed-dtoa.cc +405 -0
  180. data/lib/libv8/v8/src/fixed-dtoa.h +55 -0
  181. data/lib/libv8/v8/src/flag-definitions.h +560 -0
  182. data/lib/libv8/v8/src/flags.cc +551 -0
  183. data/lib/libv8/v8/src/flags.h +79 -0
  184. data/lib/libv8/v8/src/frames-inl.h +247 -0
  185. data/lib/libv8/v8/src/frames.cc +1243 -0
  186. data/lib/libv8/v8/src/frames.h +870 -0
  187. data/lib/libv8/v8/src/full-codegen.cc +1374 -0
  188. data/lib/libv8/v8/src/full-codegen.h +771 -0
  189. data/lib/libv8/v8/src/func-name-inferrer.cc +92 -0
  190. data/lib/libv8/v8/src/func-name-inferrer.h +111 -0
  191. data/lib/libv8/v8/src/gdb-jit.cc +1555 -0
  192. data/lib/libv8/v8/src/gdb-jit.h +143 -0
  193. data/lib/libv8/v8/src/global-handles.cc +665 -0
  194. data/lib/libv8/v8/src/global-handles.h +284 -0
  195. data/lib/libv8/v8/src/globals.h +325 -0
  196. data/lib/libv8/v8/src/handles-inl.h +177 -0
  197. data/lib/libv8/v8/src/handles.cc +987 -0
  198. data/lib/libv8/v8/src/handles.h +382 -0
  199. data/lib/libv8/v8/src/hashmap.cc +230 -0
  200. data/lib/libv8/v8/src/hashmap.h +123 -0
  201. data/lib/libv8/v8/src/heap-inl.h +704 -0
  202. data/lib/libv8/v8/src/heap-profiler.cc +1173 -0
  203. data/lib/libv8/v8/src/heap-profiler.h +397 -0
  204. data/lib/libv8/v8/src/heap.cc +5930 -0
  205. data/lib/libv8/v8/src/heap.h +2268 -0
  206. data/lib/libv8/v8/src/hydrogen-instructions.cc +1769 -0
  207. data/lib/libv8/v8/src/hydrogen-instructions.h +3971 -0
  208. data/lib/libv8/v8/src/hydrogen.cc +6239 -0
  209. data/lib/libv8/v8/src/hydrogen.h +1202 -0
  210. data/lib/libv8/v8/src/ia32/assembler-ia32-inl.h +446 -0
  211. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +2487 -0
  212. data/lib/libv8/v8/src/ia32/assembler-ia32.h +1144 -0
  213. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +1621 -0
  214. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +6198 -0
  215. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +517 -0
  216. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +265 -0
  217. data/lib/libv8/v8/src/ia32/codegen-ia32.h +79 -0
  218. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +88 -0
  219. data/lib/libv8/v8/src/ia32/debug-ia32.cc +312 -0
  220. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +774 -0
  221. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +1628 -0
  222. data/lib/libv8/v8/src/ia32/frames-ia32.cc +45 -0
  223. data/lib/libv8/v8/src/ia32/frames-ia32.h +142 -0
  224. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +4338 -0
  225. data/lib/libv8/v8/src/ia32/ic-ia32.cc +1597 -0
  226. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +4461 -0
  227. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +375 -0
  228. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +475 -0
  229. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.h +110 -0
  230. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +2261 -0
  231. data/lib/libv8/v8/src/ia32/lithium-ia32.h +2396 -0
  232. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +2136 -0
  233. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +775 -0
  234. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +1263 -0
  235. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +216 -0
  236. data/lib/libv8/v8/src/ia32/simulator-ia32.cc +30 -0
  237. data/lib/libv8/v8/src/ia32/simulator-ia32.h +74 -0
  238. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +3847 -0
  239. data/lib/libv8/v8/src/ic-inl.h +130 -0
  240. data/lib/libv8/v8/src/ic.cc +2577 -0
  241. data/lib/libv8/v8/src/ic.h +736 -0
  242. data/lib/libv8/v8/src/inspector.cc +63 -0
  243. data/lib/libv8/v8/src/inspector.h +62 -0
  244. data/lib/libv8/v8/src/interpreter-irregexp.cc +659 -0
  245. data/lib/libv8/v8/src/interpreter-irregexp.h +49 -0
  246. data/lib/libv8/v8/src/isolate-inl.h +50 -0
  247. data/lib/libv8/v8/src/isolate.cc +1869 -0
  248. data/lib/libv8/v8/src/isolate.h +1382 -0
  249. data/lib/libv8/v8/src/json-parser.cc +504 -0
  250. data/lib/libv8/v8/src/json-parser.h +161 -0
  251. data/lib/libv8/v8/src/json.js +342 -0
  252. data/lib/libv8/v8/src/jsregexp.cc +5385 -0
  253. data/lib/libv8/v8/src/jsregexp.h +1492 -0
  254. data/lib/libv8/v8/src/list-inl.h +212 -0
  255. data/lib/libv8/v8/src/list.h +174 -0
  256. data/lib/libv8/v8/src/lithium-allocator-inl.h +142 -0
  257. data/lib/libv8/v8/src/lithium-allocator.cc +2123 -0
  258. data/lib/libv8/v8/src/lithium-allocator.h +630 -0
  259. data/lib/libv8/v8/src/lithium.cc +190 -0
  260. data/lib/libv8/v8/src/lithium.h +597 -0
  261. data/lib/libv8/v8/src/liveedit-debugger.js +1082 -0
  262. data/lib/libv8/v8/src/liveedit.cc +1691 -0
  263. data/lib/libv8/v8/src/liveedit.h +180 -0
  264. data/lib/libv8/v8/src/liveobjectlist-inl.h +126 -0
  265. data/lib/libv8/v8/src/liveobjectlist.cc +2589 -0
  266. data/lib/libv8/v8/src/liveobjectlist.h +322 -0
  267. data/lib/libv8/v8/src/log-inl.h +59 -0
  268. data/lib/libv8/v8/src/log-utils.cc +428 -0
  269. data/lib/libv8/v8/src/log-utils.h +231 -0
  270. data/lib/libv8/v8/src/log.cc +1993 -0
  271. data/lib/libv8/v8/src/log.h +476 -0
  272. data/lib/libv8/v8/src/macro-assembler.h +120 -0
  273. data/lib/libv8/v8/src/macros.py +178 -0
  274. data/lib/libv8/v8/src/mark-compact.cc +3143 -0
  275. data/lib/libv8/v8/src/mark-compact.h +506 -0
  276. data/lib/libv8/v8/src/math.js +264 -0
  277. data/lib/libv8/v8/src/messages.cc +179 -0
  278. data/lib/libv8/v8/src/messages.h +113 -0
  279. data/lib/libv8/v8/src/messages.js +1096 -0
  280. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +312 -0
  281. data/lib/libv8/v8/src/mips/assembler-mips.cc +1960 -0
  282. data/lib/libv8/v8/src/mips/assembler-mips.h +1138 -0
  283. data/lib/libv8/v8/src/mips/builtins-mips.cc +1628 -0
  284. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +6656 -0
  285. data/lib/libv8/v8/src/mips/code-stubs-mips.h +682 -0
  286. data/lib/libv8/v8/src/mips/codegen-mips.cc +52 -0
  287. data/lib/libv8/v8/src/mips/codegen-mips.h +98 -0
  288. data/lib/libv8/v8/src/mips/constants-mips.cc +352 -0
  289. data/lib/libv8/v8/src/mips/constants-mips.h +739 -0
  290. data/lib/libv8/v8/src/mips/cpu-mips.cc +96 -0
  291. data/lib/libv8/v8/src/mips/debug-mips.cc +308 -0
  292. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +91 -0
  293. data/lib/libv8/v8/src/mips/disasm-mips.cc +1050 -0
  294. data/lib/libv8/v8/src/mips/frames-mips.cc +47 -0
  295. data/lib/libv8/v8/src/mips/frames-mips.h +219 -0
  296. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +4388 -0
  297. data/lib/libv8/v8/src/mips/ic-mips.cc +1580 -0
  298. data/lib/libv8/v8/src/mips/lithium-codegen-mips.h +65 -0
  299. data/lib/libv8/v8/src/mips/lithium-mips.h +307 -0
  300. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +4056 -0
  301. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +1214 -0
  302. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +1251 -0
  303. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +252 -0
  304. data/lib/libv8/v8/src/mips/simulator-mips.cc +2621 -0
  305. data/lib/libv8/v8/src/mips/simulator-mips.h +401 -0
  306. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +4285 -0
  307. data/lib/libv8/v8/src/mirror-debugger.js +2382 -0
  308. data/lib/libv8/v8/src/mksnapshot.cc +328 -0
  309. data/lib/libv8/v8/src/natives.h +64 -0
  310. data/lib/libv8/v8/src/objects-debug.cc +738 -0
  311. data/lib/libv8/v8/src/objects-inl.h +4323 -0
  312. data/lib/libv8/v8/src/objects-printer.cc +829 -0
  313. data/lib/libv8/v8/src/objects-visiting.cc +148 -0
  314. data/lib/libv8/v8/src/objects-visiting.h +424 -0
  315. data/lib/libv8/v8/src/objects.cc +10585 -0
  316. data/lib/libv8/v8/src/objects.h +6838 -0
  317. data/lib/libv8/v8/src/parser.cc +4997 -0
  318. data/lib/libv8/v8/src/parser.h +765 -0
  319. data/lib/libv8/v8/src/platform-cygwin.cc +779 -0
  320. data/lib/libv8/v8/src/platform-freebsd.cc +826 -0
  321. data/lib/libv8/v8/src/platform-linux.cc +1149 -0
  322. data/lib/libv8/v8/src/platform-macos.cc +830 -0
  323. data/lib/libv8/v8/src/platform-nullos.cc +479 -0
  324. data/lib/libv8/v8/src/platform-openbsd.cc +640 -0
  325. data/lib/libv8/v8/src/platform-posix.cc +424 -0
  326. data/lib/libv8/v8/src/platform-solaris.cc +762 -0
  327. data/lib/libv8/v8/src/platform-tls-mac.h +62 -0
  328. data/lib/libv8/v8/src/platform-tls-win32.h +62 -0
  329. data/lib/libv8/v8/src/platform-tls.h +50 -0
  330. data/lib/libv8/v8/src/platform-win32.cc +2021 -0
  331. data/lib/libv8/v8/src/platform.h +667 -0
  332. data/lib/libv8/v8/src/preparse-data-format.h +62 -0
  333. data/lib/libv8/v8/src/preparse-data.cc +183 -0
  334. data/lib/libv8/v8/src/preparse-data.h +225 -0
  335. data/lib/libv8/v8/src/preparser-api.cc +220 -0
  336. data/lib/libv8/v8/src/preparser.cc +1450 -0
  337. data/lib/libv8/v8/src/preparser.h +493 -0
  338. data/lib/libv8/v8/src/prettyprinter.cc +1493 -0
  339. data/lib/libv8/v8/src/prettyprinter.h +223 -0
  340. data/lib/libv8/v8/src/profile-generator-inl.h +128 -0
  341. data/lib/libv8/v8/src/profile-generator.cc +3098 -0
  342. data/lib/libv8/v8/src/profile-generator.h +1126 -0
  343. data/lib/libv8/v8/src/property.cc +105 -0
  344. data/lib/libv8/v8/src/property.h +365 -0
  345. data/lib/libv8/v8/src/proxy.js +83 -0
  346. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp-inl.h +78 -0
  347. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.cc +471 -0
  348. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.h +142 -0
  349. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.cc +373 -0
  350. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.h +104 -0
  351. data/lib/libv8/v8/src/regexp-macro-assembler.cc +267 -0
  352. data/lib/libv8/v8/src/regexp-macro-assembler.h +243 -0
  353. data/lib/libv8/v8/src/regexp-stack.cc +111 -0
  354. data/lib/libv8/v8/src/regexp-stack.h +147 -0
  355. data/lib/libv8/v8/src/regexp.js +483 -0
  356. data/lib/libv8/v8/src/rewriter.cc +360 -0
  357. data/lib/libv8/v8/src/rewriter.h +50 -0
  358. data/lib/libv8/v8/src/runtime-profiler.cc +489 -0
  359. data/lib/libv8/v8/src/runtime-profiler.h +201 -0
  360. data/lib/libv8/v8/src/runtime.cc +12227 -0
  361. data/lib/libv8/v8/src/runtime.h +652 -0
  362. data/lib/libv8/v8/src/runtime.js +649 -0
  363. data/lib/libv8/v8/src/safepoint-table.cc +256 -0
  364. data/lib/libv8/v8/src/safepoint-table.h +270 -0
  365. data/lib/libv8/v8/src/scanner-base.cc +952 -0
  366. data/lib/libv8/v8/src/scanner-base.h +670 -0
  367. data/lib/libv8/v8/src/scanner.cc +345 -0
  368. data/lib/libv8/v8/src/scanner.h +146 -0
  369. data/lib/libv8/v8/src/scopeinfo.cc +646 -0
  370. data/lib/libv8/v8/src/scopeinfo.h +254 -0
  371. data/lib/libv8/v8/src/scopes.cc +1150 -0
  372. data/lib/libv8/v8/src/scopes.h +507 -0
  373. data/lib/libv8/v8/src/serialize.cc +1574 -0
  374. data/lib/libv8/v8/src/serialize.h +589 -0
  375. data/lib/libv8/v8/src/shell.h +55 -0
  376. data/lib/libv8/v8/src/simulator.h +43 -0
  377. data/lib/libv8/v8/src/small-pointer-list.h +163 -0
  378. data/lib/libv8/v8/src/smart-pointer.h +109 -0
  379. data/lib/libv8/v8/src/snapshot-common.cc +83 -0
  380. data/lib/libv8/v8/src/snapshot-empty.cc +54 -0
  381. data/lib/libv8/v8/src/snapshot.h +91 -0
  382. data/lib/libv8/v8/src/spaces-inl.h +529 -0
  383. data/lib/libv8/v8/src/spaces.cc +3145 -0
  384. data/lib/libv8/v8/src/spaces.h +2369 -0
  385. data/lib/libv8/v8/src/splay-tree-inl.h +310 -0
  386. data/lib/libv8/v8/src/splay-tree.h +205 -0
  387. data/lib/libv8/v8/src/string-search.cc +41 -0
  388. data/lib/libv8/v8/src/string-search.h +568 -0
  389. data/lib/libv8/v8/src/string-stream.cc +592 -0
  390. data/lib/libv8/v8/src/string-stream.h +191 -0
  391. data/lib/libv8/v8/src/string.js +994 -0
  392. data/lib/libv8/v8/src/strtod.cc +440 -0
  393. data/lib/libv8/v8/src/strtod.h +40 -0
  394. data/lib/libv8/v8/src/stub-cache.cc +1965 -0
  395. data/lib/libv8/v8/src/stub-cache.h +924 -0
  396. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +3925 -0
  397. data/lib/libv8/v8/src/token.cc +63 -0
  398. data/lib/libv8/v8/src/token.h +288 -0
  399. data/lib/libv8/v8/src/type-info.cc +507 -0
  400. data/lib/libv8/v8/src/type-info.h +272 -0
  401. data/lib/libv8/v8/src/unbound-queue-inl.h +95 -0
  402. data/lib/libv8/v8/src/unbound-queue.h +69 -0
  403. data/lib/libv8/v8/src/unicode-inl.h +238 -0
  404. data/lib/libv8/v8/src/unicode.cc +1624 -0
  405. data/lib/libv8/v8/src/unicode.h +280 -0
  406. data/lib/libv8/v8/src/uri.js +408 -0
  407. data/lib/libv8/v8/src/utils-inl.h +48 -0
  408. data/lib/libv8/v8/src/utils.cc +371 -0
  409. data/lib/libv8/v8/src/utils.h +800 -0
  410. data/lib/libv8/v8/src/v8-counters.cc +62 -0
  411. data/lib/libv8/v8/src/v8-counters.h +314 -0
  412. data/lib/libv8/v8/src/v8.cc +213 -0
  413. data/lib/libv8/v8/src/v8.h +131 -0
  414. data/lib/libv8/v8/src/v8checks.h +64 -0
  415. data/lib/libv8/v8/src/v8dll-main.cc +44 -0
  416. data/lib/libv8/v8/src/v8globals.h +512 -0
  417. data/lib/libv8/v8/src/v8memory.h +82 -0
  418. data/lib/libv8/v8/src/v8natives.js +1310 -0
  419. data/lib/libv8/v8/src/v8preparserdll-main.cc +39 -0
  420. data/lib/libv8/v8/src/v8threads.cc +464 -0
  421. data/lib/libv8/v8/src/v8threads.h +165 -0
  422. data/lib/libv8/v8/src/v8utils.h +319 -0
  423. data/lib/libv8/v8/src/variables.cc +114 -0
  424. data/lib/libv8/v8/src/variables.h +167 -0
  425. data/lib/libv8/v8/src/version.cc +116 -0
  426. data/lib/libv8/v8/src/version.h +68 -0
  427. data/lib/libv8/v8/src/vm-state-inl.h +138 -0
  428. data/lib/libv8/v8/src/vm-state.h +71 -0
  429. data/lib/libv8/v8/src/win32-headers.h +96 -0
  430. data/lib/libv8/v8/src/x64/assembler-x64-inl.h +462 -0
  431. data/lib/libv8/v8/src/x64/assembler-x64.cc +3027 -0
  432. data/lib/libv8/v8/src/x64/assembler-x64.h +1633 -0
  433. data/lib/libv8/v8/src/x64/builtins-x64.cc +1520 -0
  434. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +5132 -0
  435. data/lib/libv8/v8/src/x64/code-stubs-x64.h +514 -0
  436. data/lib/libv8/v8/src/x64/codegen-x64.cc +146 -0
  437. data/lib/libv8/v8/src/x64/codegen-x64.h +76 -0
  438. data/lib/libv8/v8/src/x64/cpu-x64.cc +88 -0
  439. data/lib/libv8/v8/src/x64/debug-x64.cc +319 -0
  440. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +815 -0
  441. data/lib/libv8/v8/src/x64/disasm-x64.cc +1832 -0
  442. data/lib/libv8/v8/src/x64/frames-x64.cc +45 -0
  443. data/lib/libv8/v8/src/x64/frames-x64.h +130 -0
  444. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +4318 -0
  445. data/lib/libv8/v8/src/x64/ic-x64.cc +1608 -0
  446. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +4267 -0
  447. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +367 -0
  448. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.cc +320 -0
  449. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.h +74 -0
  450. data/lib/libv8/v8/src/x64/lithium-x64.cc +2202 -0
  451. data/lib/libv8/v8/src/x64/lithium-x64.h +2333 -0
  452. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +3745 -0
  453. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +1290 -0
  454. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +1398 -0
  455. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +282 -0
  456. data/lib/libv8/v8/src/x64/simulator-x64.cc +27 -0
  457. data/lib/libv8/v8/src/x64/simulator-x64.h +72 -0
  458. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +3610 -0
  459. data/lib/libv8/v8/src/zone-inl.h +140 -0
  460. data/lib/libv8/v8/src/zone.cc +196 -0
  461. data/lib/libv8/v8/src/zone.h +240 -0
  462. data/lib/libv8/v8/tools/codemap.js +265 -0
  463. data/lib/libv8/v8/tools/consarray.js +93 -0
  464. data/lib/libv8/v8/tools/csvparser.js +78 -0
  465. data/lib/libv8/v8/tools/disasm.py +92 -0
  466. data/lib/libv8/v8/tools/freebsd-tick-processor +10 -0
  467. data/lib/libv8/v8/tools/gc-nvp-trace-processor.py +342 -0
  468. data/lib/libv8/v8/tools/gcmole/README +62 -0
  469. data/lib/libv8/v8/tools/gcmole/gccause.lua +60 -0
  470. data/lib/libv8/v8/tools/gcmole/gcmole.cc +1261 -0
  471. data/lib/libv8/v8/tools/gcmole/gcmole.lua +378 -0
  472. data/lib/libv8/v8/tools/generate-ten-powers.scm +286 -0
  473. data/lib/libv8/v8/tools/grokdump.py +841 -0
  474. data/lib/libv8/v8/tools/gyp/v8.gyp +995 -0
  475. data/lib/libv8/v8/tools/js2c.py +364 -0
  476. data/lib/libv8/v8/tools/jsmin.py +280 -0
  477. data/lib/libv8/v8/tools/linux-tick-processor +35 -0
  478. data/lib/libv8/v8/tools/ll_prof.py +942 -0
  479. data/lib/libv8/v8/tools/logreader.js +185 -0
  480. data/lib/libv8/v8/tools/mac-nm +18 -0
  481. data/lib/libv8/v8/tools/mac-tick-processor +6 -0
  482. data/lib/libv8/v8/tools/oom_dump/README +31 -0
  483. data/lib/libv8/v8/tools/oom_dump/SConstruct +42 -0
  484. data/lib/libv8/v8/tools/oom_dump/oom_dump.cc +288 -0
  485. data/lib/libv8/v8/tools/presubmit.py +305 -0
  486. data/lib/libv8/v8/tools/process-heap-prof.py +120 -0
  487. data/lib/libv8/v8/tools/profile.js +751 -0
  488. data/lib/libv8/v8/tools/profile_view.js +219 -0
  489. data/lib/libv8/v8/tools/run-valgrind.py +77 -0
  490. data/lib/libv8/v8/tools/splaytree.js +316 -0
  491. data/lib/libv8/v8/tools/stats-viewer.py +468 -0
  492. data/lib/libv8/v8/tools/test.py +1510 -0
  493. data/lib/libv8/v8/tools/tickprocessor-driver.js +59 -0
  494. data/lib/libv8/v8/tools/tickprocessor.js +877 -0
  495. data/lib/libv8/v8/tools/utils.py +96 -0
  496. data/lib/libv8/v8/tools/visual_studio/README.txt +12 -0
  497. data/lib/libv8/v8/tools/windows-tick-processor.bat +30 -0
  498. data/lib/libv8/version.rb +5 -0
  499. data/libv8.gemspec +36 -0
  500. metadata +578 -0
@@ -0,0 +1,446 @@
1
+ // Copyright (c) 1994-2006 Sun Microsystems Inc.
2
+ // All Rights Reserved.
3
+ //
4
+ // Redistribution and use in source and binary forms, with or without
5
+ // modification, are permitted provided that the following conditions are
6
+ // met:
7
+ //
8
+ // - Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ //
11
+ // - Redistribution in binary form must reproduce the above copyright
12
+ // notice, this list of conditions and the following disclaimer in the
13
+ // documentation and/or other materials provided with the distribution.
14
+ //
15
+ // - Neither the name of Sun Microsystems or the names of contributors may
16
+ // be used to endorse or promote products derived from this software without
17
+ // specific prior written permission.
18
+ //
19
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
+ // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
+ // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
+ // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
+ // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
+ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
+ // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
+ // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
+ // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ // The original source code covered by the above license above has been
32
+ // modified significantly by Google Inc.
33
+ // Copyright 2011 the V8 project authors. All rights reserved.
34
+
35
+ // A light-weight IA32 Assembler.
36
+
37
+ #ifndef V8_IA32_ASSEMBLER_IA32_INL_H_
38
+ #define V8_IA32_ASSEMBLER_IA32_INL_H_
39
+
40
+ #include "cpu.h"
41
+ #include "debug.h"
42
+
43
+ namespace v8 {
44
+ namespace internal {
45
+
46
+
47
+ // The modes possibly affected by apply must be in kApplyMask.
48
+ void RelocInfo::apply(intptr_t delta) {
49
+ if (rmode_ == RUNTIME_ENTRY || IsCodeTarget(rmode_)) {
50
+ int32_t* p = reinterpret_cast<int32_t*>(pc_);
51
+ *p -= delta; // Relocate entry.
52
+ CPU::FlushICache(p, sizeof(uint32_t));
53
+ } else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) {
54
+ // Special handling of js_return when a break point is set (call
55
+ // instruction has been inserted).
56
+ int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
57
+ *p -= delta; // Relocate entry.
58
+ CPU::FlushICache(p, sizeof(uint32_t));
59
+ } else if (rmode_ == DEBUG_BREAK_SLOT && IsPatchedDebugBreakSlotSequence()) {
60
+ // Special handling of a debug break slot when a break point is set (call
61
+ // instruction has been inserted).
62
+ int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
63
+ *p -= delta; // Relocate entry.
64
+ CPU::FlushICache(p, sizeof(uint32_t));
65
+ } else if (IsInternalReference(rmode_)) {
66
+ // absolute code pointer inside code object moves with the code object.
67
+ int32_t* p = reinterpret_cast<int32_t*>(pc_);
68
+ *p += delta; // Relocate entry.
69
+ CPU::FlushICache(p, sizeof(uint32_t));
70
+ }
71
+ }
72
+
73
+
74
+ Address RelocInfo::target_address() {
75
+ ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
76
+ return Assembler::target_address_at(pc_);
77
+ }
78
+
79
+
80
+ Address RelocInfo::target_address_address() {
81
+ ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
82
+ return reinterpret_cast<Address>(pc_);
83
+ }
84
+
85
+
86
+ int RelocInfo::target_address_size() {
87
+ return Assembler::kExternalTargetSize;
88
+ }
89
+
90
+
91
+ void RelocInfo::set_target_address(Address target) {
92
+ ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
93
+ Assembler::set_target_address_at(pc_, target);
94
+ }
95
+
96
+
97
+ Object* RelocInfo::target_object() {
98
+ ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
99
+ return Memory::Object_at(pc_);
100
+ }
101
+
102
+
103
+ Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
104
+ ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
105
+ return Memory::Object_Handle_at(pc_);
106
+ }
107
+
108
+
109
+ Object** RelocInfo::target_object_address() {
110
+ ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
111
+ return &Memory::Object_at(pc_);
112
+ }
113
+
114
+
115
+ void RelocInfo::set_target_object(Object* target) {
116
+ ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
117
+ Memory::Object_at(pc_) = target;
118
+ CPU::FlushICache(pc_, sizeof(Address));
119
+ }
120
+
121
+
122
+ Address* RelocInfo::target_reference_address() {
123
+ ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
124
+ return reinterpret_cast<Address*>(pc_);
125
+ }
126
+
127
+
128
+ Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
129
+ ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
130
+ Address address = Memory::Address_at(pc_);
131
+ return Handle<JSGlobalPropertyCell>(
132
+ reinterpret_cast<JSGlobalPropertyCell**>(address));
133
+ }
134
+
135
+
136
+ JSGlobalPropertyCell* RelocInfo::target_cell() {
137
+ ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
138
+ Address address = Memory::Address_at(pc_);
139
+ Object* object = HeapObject::FromAddress(
140
+ address - JSGlobalPropertyCell::kValueOffset);
141
+ return reinterpret_cast<JSGlobalPropertyCell*>(object);
142
+ }
143
+
144
+
145
+ void RelocInfo::set_target_cell(JSGlobalPropertyCell* cell) {
146
+ ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
147
+ Address address = cell->address() + JSGlobalPropertyCell::kValueOffset;
148
+ Memory::Address_at(pc_) = address;
149
+ CPU::FlushICache(pc_, sizeof(Address));
150
+ }
151
+
152
+
153
+ Address RelocInfo::call_address() {
154
+ ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
155
+ (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
156
+ return Assembler::target_address_at(pc_ + 1);
157
+ }
158
+
159
+
160
+ void RelocInfo::set_call_address(Address target) {
161
+ ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
162
+ (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
163
+ Assembler::set_target_address_at(pc_ + 1, target);
164
+ }
165
+
166
+
167
+ Object* RelocInfo::call_object() {
168
+ return *call_object_address();
169
+ }
170
+
171
+
172
+ void RelocInfo::set_call_object(Object* target) {
173
+ *call_object_address() = target;
174
+ }
175
+
176
+
177
+ Object** RelocInfo::call_object_address() {
178
+ ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
179
+ (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
180
+ return reinterpret_cast<Object**>(pc_ + 1);
181
+ }
182
+
183
+
184
+ bool RelocInfo::IsPatchedReturnSequence() {
185
+ return *pc_ == 0xE8;
186
+ }
187
+
188
+
189
+ bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
190
+ return !Assembler::IsNop(pc());
191
+ }
192
+
193
+
194
+ void RelocInfo::Visit(ObjectVisitor* visitor) {
195
+ RelocInfo::Mode mode = rmode();
196
+ if (mode == RelocInfo::EMBEDDED_OBJECT) {
197
+ visitor->VisitPointer(target_object_address());
198
+ CPU::FlushICache(pc_, sizeof(Address));
199
+ } else if (RelocInfo::IsCodeTarget(mode)) {
200
+ visitor->VisitCodeTarget(this);
201
+ } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
202
+ visitor->VisitGlobalPropertyCell(this);
203
+ } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
204
+ visitor->VisitExternalReference(target_reference_address());
205
+ CPU::FlushICache(pc_, sizeof(Address));
206
+ #ifdef ENABLE_DEBUGGER_SUPPORT
207
+ // TODO(isolates): Get a cached isolate below.
208
+ } else if (((RelocInfo::IsJSReturn(mode) &&
209
+ IsPatchedReturnSequence()) ||
210
+ (RelocInfo::IsDebugBreakSlot(mode) &&
211
+ IsPatchedDebugBreakSlotSequence())) &&
212
+ Isolate::Current()->debug()->has_break_points()) {
213
+ visitor->VisitDebugTarget(this);
214
+ #endif
215
+ } else if (mode == RelocInfo::RUNTIME_ENTRY) {
216
+ visitor->VisitRuntimeEntry(this);
217
+ }
218
+ }
219
+
220
+
221
+ template<typename StaticVisitor>
222
+ void RelocInfo::Visit(Heap* heap) {
223
+ RelocInfo::Mode mode = rmode();
224
+ if (mode == RelocInfo::EMBEDDED_OBJECT) {
225
+ StaticVisitor::VisitPointer(heap, target_object_address());
226
+ CPU::FlushICache(pc_, sizeof(Address));
227
+ } else if (RelocInfo::IsCodeTarget(mode)) {
228
+ StaticVisitor::VisitCodeTarget(heap, this);
229
+ } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
230
+ StaticVisitor::VisitGlobalPropertyCell(heap, this);
231
+ } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
232
+ StaticVisitor::VisitExternalReference(target_reference_address());
233
+ CPU::FlushICache(pc_, sizeof(Address));
234
+ #ifdef ENABLE_DEBUGGER_SUPPORT
235
+ } else if (heap->isolate()->debug()->has_break_points() &&
236
+ ((RelocInfo::IsJSReturn(mode) &&
237
+ IsPatchedReturnSequence()) ||
238
+ (RelocInfo::IsDebugBreakSlot(mode) &&
239
+ IsPatchedDebugBreakSlotSequence()))) {
240
+ StaticVisitor::VisitDebugTarget(heap, this);
241
+ #endif
242
+ } else if (mode == RelocInfo::RUNTIME_ENTRY) {
243
+ StaticVisitor::VisitRuntimeEntry(this);
244
+ }
245
+ }
246
+
247
+
248
+
249
+ Immediate::Immediate(int x) {
250
+ x_ = x;
251
+ rmode_ = RelocInfo::NONE;
252
+ }
253
+
254
+
255
+ Immediate::Immediate(const ExternalReference& ext) {
256
+ x_ = reinterpret_cast<int32_t>(ext.address());
257
+ rmode_ = RelocInfo::EXTERNAL_REFERENCE;
258
+ }
259
+
260
+
261
+ Immediate::Immediate(Label* internal_offset) {
262
+ x_ = reinterpret_cast<int32_t>(internal_offset);
263
+ rmode_ = RelocInfo::INTERNAL_REFERENCE;
264
+ }
265
+
266
+
267
+ Immediate::Immediate(Handle<Object> handle) {
268
+ // Verify all Objects referred by code are NOT in new space.
269
+ Object* obj = *handle;
270
+ ASSERT(!HEAP->InNewSpace(obj));
271
+ if (obj->IsHeapObject()) {
272
+ x_ = reinterpret_cast<intptr_t>(handle.location());
273
+ rmode_ = RelocInfo::EMBEDDED_OBJECT;
274
+ } else {
275
+ // no relocation needed
276
+ x_ = reinterpret_cast<intptr_t>(obj);
277
+ rmode_ = RelocInfo::NONE;
278
+ }
279
+ }
280
+
281
+
282
+ Immediate::Immediate(Smi* value) {
283
+ x_ = reinterpret_cast<intptr_t>(value);
284
+ rmode_ = RelocInfo::NONE;
285
+ }
286
+
287
+
288
+ Immediate::Immediate(Address addr) {
289
+ x_ = reinterpret_cast<int32_t>(addr);
290
+ rmode_ = RelocInfo::NONE;
291
+ }
292
+
293
+
294
+ void Assembler::emit(uint32_t x) {
295
+ *reinterpret_cast<uint32_t*>(pc_) = x;
296
+ pc_ += sizeof(uint32_t);
297
+ }
298
+
299
+
300
+ void Assembler::emit(Handle<Object> handle) {
301
+ // Verify all Objects referred by code are NOT in new space.
302
+ Object* obj = *handle;
303
+ ASSERT(!isolate()->heap()->InNewSpace(obj));
304
+ if (obj->IsHeapObject()) {
305
+ emit(reinterpret_cast<intptr_t>(handle.location()),
306
+ RelocInfo::EMBEDDED_OBJECT);
307
+ } else {
308
+ // no relocation needed
309
+ emit(reinterpret_cast<intptr_t>(obj));
310
+ }
311
+ }
312
+
313
+
314
+ void Assembler::emit(uint32_t x, RelocInfo::Mode rmode, unsigned id) {
315
+ if (rmode == RelocInfo::CODE_TARGET && id != kNoASTId) {
316
+ RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, static_cast<intptr_t>(id));
317
+ } else if (rmode != RelocInfo::NONE) {
318
+ RecordRelocInfo(rmode);
319
+ }
320
+ emit(x);
321
+ }
322
+
323
+
324
+ void Assembler::emit(const Immediate& x) {
325
+ if (x.rmode_ == RelocInfo::INTERNAL_REFERENCE) {
326
+ Label* label = reinterpret_cast<Label*>(x.x_);
327
+ emit_code_relative_offset(label);
328
+ return;
329
+ }
330
+ if (x.rmode_ != RelocInfo::NONE) RecordRelocInfo(x.rmode_);
331
+ emit(x.x_);
332
+ }
333
+
334
+
335
+ void Assembler::emit_code_relative_offset(Label* label) {
336
+ if (label->is_bound()) {
337
+ int32_t pos;
338
+ pos = label->pos() + Code::kHeaderSize - kHeapObjectTag;
339
+ emit(pos);
340
+ } else {
341
+ emit_disp(label, Displacement::CODE_RELATIVE);
342
+ }
343
+ }
344
+
345
+
346
+ void Assembler::emit_w(const Immediate& x) {
347
+ ASSERT(x.rmode_ == RelocInfo::NONE);
348
+ uint16_t value = static_cast<uint16_t>(x.x_);
349
+ reinterpret_cast<uint16_t*>(pc_)[0] = value;
350
+ pc_ += sizeof(uint16_t);
351
+ }
352
+
353
+
354
+ Address Assembler::target_address_at(Address pc) {
355
+ return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc);
356
+ }
357
+
358
+
359
+ void Assembler::set_target_address_at(Address pc, Address target) {
360
+ int32_t* p = reinterpret_cast<int32_t*>(pc);
361
+ *p = target - (pc + sizeof(int32_t));
362
+ CPU::FlushICache(p, sizeof(int32_t));
363
+ }
364
+
365
+
366
+ Displacement Assembler::disp_at(Label* L) {
367
+ return Displacement(long_at(L->pos()));
368
+ }
369
+
370
+
371
+ void Assembler::disp_at_put(Label* L, Displacement disp) {
372
+ long_at_put(L->pos(), disp.data());
373
+ }
374
+
375
+
376
+ void Assembler::emit_disp(Label* L, Displacement::Type type) {
377
+ Displacement disp(L, type);
378
+ L->link_to(pc_offset());
379
+ emit(static_cast<int>(disp.data()));
380
+ }
381
+
382
+
383
+ void Assembler::emit_near_disp(Label* L) {
384
+ byte disp = 0x00;
385
+ if (L->is_near_linked()) {
386
+ int offset = L->near_link_pos() - pc_offset();
387
+ ASSERT(is_int8(offset));
388
+ disp = static_cast<byte>(offset & 0xFF);
389
+ }
390
+ L->link_to(pc_offset(), Label::kNear);
391
+ *pc_++ = disp;
392
+ }
393
+
394
+
395
+ void Operand::set_modrm(int mod, Register rm) {
396
+ ASSERT((mod & -4) == 0);
397
+ buf_[0] = mod << 6 | rm.code();
398
+ len_ = 1;
399
+ }
400
+
401
+
402
+ void Operand::set_sib(ScaleFactor scale, Register index, Register base) {
403
+ ASSERT(len_ == 1);
404
+ ASSERT((scale & -4) == 0);
405
+ // Use SIB with no index register only for base esp.
406
+ ASSERT(!index.is(esp) || base.is(esp));
407
+ buf_[1] = scale << 6 | index.code() << 3 | base.code();
408
+ len_ = 2;
409
+ }
410
+
411
+
412
+ void Operand::set_disp8(int8_t disp) {
413
+ ASSERT(len_ == 1 || len_ == 2);
414
+ *reinterpret_cast<int8_t*>(&buf_[len_++]) = disp;
415
+ }
416
+
417
+
418
+ void Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) {
419
+ ASSERT(len_ == 1 || len_ == 2);
420
+ int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);
421
+ *p = disp;
422
+ len_ += sizeof(int32_t);
423
+ rmode_ = rmode;
424
+ }
425
+
426
+ Operand::Operand(Register reg) {
427
+ // reg
428
+ set_modrm(3, reg);
429
+ }
430
+
431
+
432
+ Operand::Operand(XMMRegister xmm_reg) {
433
+ Register reg = { xmm_reg.code() };
434
+ set_modrm(3, reg);
435
+ }
436
+
437
+
438
+ Operand::Operand(int32_t disp, RelocInfo::Mode rmode) {
439
+ // [disp/r]
440
+ set_modrm(0, ebp);
441
+ set_dispr(disp, rmode);
442
+ }
443
+
444
+ } } // namespace v8::internal
445
+
446
+ #endif // V8_IA32_ASSEMBLER_IA32_INL_H_
@@ -0,0 +1,2487 @@
1
+ // Copyright (c) 1994-2006 Sun Microsystems Inc.
2
+ // All Rights Reserved.
3
+ //
4
+ // Redistribution and use in source and binary forms, with or without
5
+ // modification, are permitted provided that the following conditions
6
+ // are met:
7
+ //
8
+ // - Redistributions of source code must retain the above copyright notice,
9
+ // this list of conditions and the following disclaimer.
10
+ //
11
+ // - Redistribution in binary form must reproduce the above copyright
12
+ // notice, this list of conditions and the following disclaimer in the
13
+ // documentation and/or other materials provided with the
14
+ // distribution.
15
+ //
16
+ // - Neither the name of Sun Microsystems or the names of contributors may
17
+ // be used to endorse or promote products derived from this software without
18
+ // specific prior written permission.
19
+ //
20
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23
+ // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
+ // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25
+ // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26
+ // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
+ // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29
+ // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
+ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31
+ // OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
33
+ // The original source code covered by the above license above has been modified
34
+ // significantly by Google Inc.
35
+ // Copyright 2011 the V8 project authors. All rights reserved.
36
+
37
+ #include "v8.h"
38
+
39
+ #if defined(V8_TARGET_ARCH_IA32)
40
+
41
+ #include "disassembler.h"
42
+ #include "macro-assembler.h"
43
+ #include "serialize.h"
44
+
45
+ namespace v8 {
46
+ namespace internal {
47
+
48
+ // -----------------------------------------------------------------------------
49
+ // Implementation of CpuFeatures
50
+
51
+ #ifdef DEBUG
52
+ bool CpuFeatures::initialized_ = false;
53
+ #endif
54
+ uint64_t CpuFeatures::supported_ = 0;
55
+ uint64_t CpuFeatures::found_by_runtime_probing_ = 0;
56
+
57
+
58
+ void CpuFeatures::Probe() {
59
+ ASSERT(!initialized_);
60
+ ASSERT(supported_ == 0);
61
+ #ifdef DEBUG
62
+ initialized_ = true;
63
+ #endif
64
+ if (Serializer::enabled()) {
65
+ supported_ |= OS::CpuFeaturesImpliedByPlatform();
66
+ return; // No features if we might serialize.
67
+ }
68
+
69
+ const int kBufferSize = 4 * KB;
70
+ VirtualMemory* memory = new VirtualMemory(kBufferSize);
71
+ if (!memory->IsReserved()) {
72
+ delete memory;
73
+ return;
74
+ }
75
+ ASSERT(memory->size() >= static_cast<size_t>(kBufferSize));
76
+ if (!memory->Commit(memory->address(), kBufferSize, true/*executable*/)) {
77
+ delete memory;
78
+ return;
79
+ }
80
+
81
+ Assembler assm(NULL, memory->address(), kBufferSize);
82
+ Label cpuid, done;
83
+ #define __ assm.
84
+ // Save old esp, since we are going to modify the stack.
85
+ __ push(ebp);
86
+ __ pushfd();
87
+ __ push(ecx);
88
+ __ push(ebx);
89
+ __ mov(ebp, Operand(esp));
90
+
91
+ // If we can modify bit 21 of the EFLAGS register, then CPUID is supported.
92
+ __ pushfd();
93
+ __ pop(eax);
94
+ __ mov(edx, Operand(eax));
95
+ __ xor_(eax, 0x200000); // Flip bit 21.
96
+ __ push(eax);
97
+ __ popfd();
98
+ __ pushfd();
99
+ __ pop(eax);
100
+ __ xor_(eax, Operand(edx)); // Different if CPUID is supported.
101
+ __ j(not_zero, &cpuid);
102
+
103
+ // CPUID not supported. Clear the supported features in edx:eax.
104
+ __ xor_(eax, Operand(eax));
105
+ __ xor_(edx, Operand(edx));
106
+ __ jmp(&done);
107
+
108
+ // Invoke CPUID with 1 in eax to get feature information in
109
+ // ecx:edx. Temporarily enable CPUID support because we know it's
110
+ // safe here.
111
+ __ bind(&cpuid);
112
+ __ mov(eax, 1);
113
+ supported_ = (1 << CPUID);
114
+ { Scope fscope(CPUID);
115
+ __ cpuid();
116
+ }
117
+ supported_ = 0;
118
+
119
+ // Move the result from ecx:edx to edx:eax and make sure to mark the
120
+ // CPUID feature as supported.
121
+ __ mov(eax, Operand(edx));
122
+ __ or_(eax, 1 << CPUID);
123
+ __ mov(edx, Operand(ecx));
124
+
125
+ // Done.
126
+ __ bind(&done);
127
+ __ mov(esp, Operand(ebp));
128
+ __ pop(ebx);
129
+ __ pop(ecx);
130
+ __ popfd();
131
+ __ pop(ebp);
132
+ __ ret(0);
133
+ #undef __
134
+
135
+ typedef uint64_t (*F0)();
136
+ F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address()));
137
+ supported_ = probe();
138
+ found_by_runtime_probing_ = supported_;
139
+ uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform();
140
+ supported_ |= os_guarantees;
141
+ found_by_runtime_probing_ &= ~os_guarantees;
142
+
143
+ delete memory;
144
+ }
145
+
146
+
147
+ // -----------------------------------------------------------------------------
148
+ // Implementation of Displacement
149
+
150
+ void Displacement::init(Label* L, Type type) {
151
+ ASSERT(!L->is_bound());
152
+ int next = 0;
153
+ if (L->is_linked()) {
154
+ next = L->pos();
155
+ ASSERT(next > 0); // Displacements must be at positions > 0
156
+ }
157
+ // Ensure that we _never_ overflow the next field.
158
+ ASSERT(NextField::is_valid(Assembler::kMaximalBufferSize));
159
+ data_ = NextField::encode(next) | TypeField::encode(type);
160
+ }
161
+
162
+
163
+ // -----------------------------------------------------------------------------
164
+ // Implementation of RelocInfo
165
+
166
+
167
+ const int RelocInfo::kApplyMask =
168
+ RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
169
+ 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE |
170
+ 1 << RelocInfo::DEBUG_BREAK_SLOT;
171
+
172
+
173
+ bool RelocInfo::IsCodedSpecially() {
174
+ // The deserializer needs to know whether a pointer is specially coded. Being
175
+ // specially coded on IA32 means that it is a relative address, as used by
176
+ // branch instructions. These are also the ones that need changing when a
177
+ // code object moves.
178
+ return (1 << rmode_) & kApplyMask;
179
+ }
180
+
181
+
182
+ void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
183
+ // Patch the code at the current address with the supplied instructions.
184
+ for (int i = 0; i < instruction_count; i++) {
185
+ *(pc_ + i) = *(instructions + i);
186
+ }
187
+
188
+ // Indicate that code has changed.
189
+ CPU::FlushICache(pc_, instruction_count);
190
+ }
191
+
192
+
193
+ // Patch the code at the current PC with a call to the target address.
194
+ // Additional guard int3 instructions can be added if required.
195
+ void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
196
+ // Call instruction takes up 5 bytes and int3 takes up one byte.
197
+ static const int kCallCodeSize = 5;
198
+ int code_size = kCallCodeSize + guard_bytes;
199
+
200
+ // Create a code patcher.
201
+ CodePatcher patcher(pc_, code_size);
202
+
203
+ // Add a label for checking the size of the code used for returning.
204
+ #ifdef DEBUG
205
+ Label check_codesize;
206
+ patcher.masm()->bind(&check_codesize);
207
+ #endif
208
+
209
+ // Patch the code.
210
+ patcher.masm()->call(target, RelocInfo::NONE);
211
+
212
+ // Check that the size of the code generated is as expected.
213
+ ASSERT_EQ(kCallCodeSize,
214
+ patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
215
+
216
+ // Add the requested number of int3 instructions after the call.
217
+ ASSERT_GE(guard_bytes, 0);
218
+ for (int i = 0; i < guard_bytes; i++) {
219
+ patcher.masm()->int3();
220
+ }
221
+ }
222
+
223
+
224
+ // -----------------------------------------------------------------------------
225
+ // Implementation of Operand
226
+
227
+ Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
228
+ // [base + disp/r]
229
+ if (disp == 0 && rmode == RelocInfo::NONE && !base.is(ebp)) {
230
+ // [base]
231
+ set_modrm(0, base);
232
+ if (base.is(esp)) set_sib(times_1, esp, base);
233
+ } else if (is_int8(disp) && rmode == RelocInfo::NONE) {
234
+ // [base + disp8]
235
+ set_modrm(1, base);
236
+ if (base.is(esp)) set_sib(times_1, esp, base);
237
+ set_disp8(disp);
238
+ } else {
239
+ // [base + disp/r]
240
+ set_modrm(2, base);
241
+ if (base.is(esp)) set_sib(times_1, esp, base);
242
+ set_dispr(disp, rmode);
243
+ }
244
+ }
245
+
246
+
247
+ Operand::Operand(Register base,
248
+ Register index,
249
+ ScaleFactor scale,
250
+ int32_t disp,
251
+ RelocInfo::Mode rmode) {
252
+ ASSERT(!index.is(esp)); // illegal addressing mode
253
+ // [base + index*scale + disp/r]
254
+ if (disp == 0 && rmode == RelocInfo::NONE && !base.is(ebp)) {
255
+ // [base + index*scale]
256
+ set_modrm(0, esp);
257
+ set_sib(scale, index, base);
258
+ } else if (is_int8(disp) && rmode == RelocInfo::NONE) {
259
+ // [base + index*scale + disp8]
260
+ set_modrm(1, esp);
261
+ set_sib(scale, index, base);
262
+ set_disp8(disp);
263
+ } else {
264
+ // [base + index*scale + disp/r]
265
+ set_modrm(2, esp);
266
+ set_sib(scale, index, base);
267
+ set_dispr(disp, rmode);
268
+ }
269
+ }
270
+
271
+
272
+ Operand::Operand(Register index,
273
+ ScaleFactor scale,
274
+ int32_t disp,
275
+ RelocInfo::Mode rmode) {
276
+ ASSERT(!index.is(esp)); // illegal addressing mode
277
+ // [index*scale + disp/r]
278
+ set_modrm(0, esp);
279
+ set_sib(scale, index, ebp);
280
+ set_dispr(disp, rmode);
281
+ }
282
+
283
+
284
+ bool Operand::is_reg(Register reg) const {
285
+ return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only.
286
+ && ((buf_[0] & 0x07) == reg.code()); // register codes match.
287
+ }
288
+
289
+ // -----------------------------------------------------------------------------
290
+ // Implementation of Assembler.
291
+
292
+ // Emit a single byte. Must always be inlined.
293
+ #define EMIT(x) \
294
+ *pc_++ = (x)
295
+
296
+
297
+ #ifdef GENERATED_CODE_COVERAGE
298
+ static void InitCoverageLog();
299
+ #endif
300
+
301
+ Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
302
+ : AssemblerBase(arg_isolate),
303
+ positions_recorder_(this),
304
+ emit_debug_code_(FLAG_debug_code) {
305
+ if (buffer == NULL) {
306
+ // Do our own buffer management.
307
+ if (buffer_size <= kMinimalBufferSize) {
308
+ buffer_size = kMinimalBufferSize;
309
+
310
+ if (isolate()->assembler_spare_buffer() != NULL) {
311
+ buffer = isolate()->assembler_spare_buffer();
312
+ isolate()->set_assembler_spare_buffer(NULL);
313
+ }
314
+ }
315
+ if (buffer == NULL) {
316
+ buffer_ = NewArray<byte>(buffer_size);
317
+ } else {
318
+ buffer_ = static_cast<byte*>(buffer);
319
+ }
320
+ buffer_size_ = buffer_size;
321
+ own_buffer_ = true;
322
+ } else {
323
+ // Use externally provided buffer instead.
324
+ ASSERT(buffer_size > 0);
325
+ buffer_ = static_cast<byte*>(buffer);
326
+ buffer_size_ = buffer_size;
327
+ own_buffer_ = false;
328
+ }
329
+
330
+ // Clear the buffer in debug mode unless it was provided by the
331
+ // caller in which case we can't be sure it's okay to overwrite
332
+ // existing code in it; see CodePatcher::CodePatcher(...).
333
+ #ifdef DEBUG
334
+ if (own_buffer_) {
335
+ memset(buffer_, 0xCC, buffer_size); // int3
336
+ }
337
+ #endif
338
+
339
+ // Setup buffer pointers.
340
+ ASSERT(buffer_ != NULL);
341
+ pc_ = buffer_;
342
+ reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
343
+
344
+ #ifdef GENERATED_CODE_COVERAGE
345
+ InitCoverageLog();
346
+ #endif
347
+ }
348
+
349
+
350
+ Assembler::~Assembler() {
351
+ if (own_buffer_) {
352
+ if (isolate()->assembler_spare_buffer() == NULL &&
353
+ buffer_size_ == kMinimalBufferSize) {
354
+ isolate()->set_assembler_spare_buffer(buffer_);
355
+ } else {
356
+ DeleteArray(buffer_);
357
+ }
358
+ }
359
+ }
360
+
361
+
362
+ void Assembler::GetCode(CodeDesc* desc) {
363
+ // Finalize code (at this point overflow() may be true, but the gap ensures
364
+ // that we are still not overlapping instructions and relocation info).
365
+ ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
366
+ // Setup code descriptor.
367
+ desc->buffer = buffer_;
368
+ desc->buffer_size = buffer_size_;
369
+ desc->instr_size = pc_offset();
370
+ desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
371
+ desc->origin = this;
372
+ }
373
+
374
+
375
+ void Assembler::Align(int m) {
376
+ ASSERT(IsPowerOf2(m));
377
+ while ((pc_offset() & (m - 1)) != 0) {
378
+ nop();
379
+ }
380
+ }
381
+
382
+
383
+ void Assembler::CodeTargetAlign() {
384
+ Align(16); // Preferred alignment of jump targets on ia32.
385
+ }
386
+
387
+
388
+ void Assembler::cpuid() {
389
+ ASSERT(CpuFeatures::IsEnabled(CPUID));
390
+ EnsureSpace ensure_space(this);
391
+ EMIT(0x0F);
392
+ EMIT(0xA2);
393
+ }
394
+
395
+
396
+ void Assembler::pushad() {
397
+ EnsureSpace ensure_space(this);
398
+ EMIT(0x60);
399
+ }
400
+
401
+
402
+ void Assembler::popad() {
403
+ EnsureSpace ensure_space(this);
404
+ EMIT(0x61);
405
+ }
406
+
407
+
408
+ void Assembler::pushfd() {
409
+ EnsureSpace ensure_space(this);
410
+ EMIT(0x9C);
411
+ }
412
+
413
+
414
+ void Assembler::popfd() {
415
+ EnsureSpace ensure_space(this);
416
+ EMIT(0x9D);
417
+ }
418
+
419
+
420
+ void Assembler::push(const Immediate& x) {
421
+ EnsureSpace ensure_space(this);
422
+ if (x.is_int8()) {
423
+ EMIT(0x6a);
424
+ EMIT(x.x_);
425
+ } else {
426
+ EMIT(0x68);
427
+ emit(x);
428
+ }
429
+ }
430
+
431
+
432
+ void Assembler::push_imm32(int32_t imm32) {
433
+ EnsureSpace ensure_space(this);
434
+ EMIT(0x68);
435
+ emit(imm32);
436
+ }
437
+
438
+
439
+ void Assembler::push(Register src) {
440
+ EnsureSpace ensure_space(this);
441
+ EMIT(0x50 | src.code());
442
+ }
443
+
444
+
445
+ void Assembler::push(const Operand& src) {
446
+ EnsureSpace ensure_space(this);
447
+ EMIT(0xFF);
448
+ emit_operand(esi, src);
449
+ }
450
+
451
+
452
+ void Assembler::pop(Register dst) {
453
+ ASSERT(reloc_info_writer.last_pc() != NULL);
454
+ EnsureSpace ensure_space(this);
455
+ EMIT(0x58 | dst.code());
456
+ }
457
+
458
+
459
+ void Assembler::pop(const Operand& dst) {
460
+ EnsureSpace ensure_space(this);
461
+ EMIT(0x8F);
462
+ emit_operand(eax, dst);
463
+ }
464
+
465
+
466
+ void Assembler::enter(const Immediate& size) {
467
+ EnsureSpace ensure_space(this);
468
+ EMIT(0xC8);
469
+ emit_w(size);
470
+ EMIT(0);
471
+ }
472
+
473
+
474
+ void Assembler::leave() {
475
+ EnsureSpace ensure_space(this);
476
+ EMIT(0xC9);
477
+ }
478
+
479
+
480
+ void Assembler::mov_b(Register dst, const Operand& src) {
481
+ ASSERT(dst.code() < 4);
482
+ EnsureSpace ensure_space(this);
483
+ EMIT(0x8A);
484
+ emit_operand(dst, src);
485
+ }
486
+
487
+
488
+ void Assembler::mov_b(const Operand& dst, int8_t imm8) {
489
+ EnsureSpace ensure_space(this);
490
+ EMIT(0xC6);
491
+ emit_operand(eax, dst);
492
+ EMIT(imm8);
493
+ }
494
+
495
+
496
+ void Assembler::mov_b(const Operand& dst, Register src) {
497
+ ASSERT(src.code() < 4);
498
+ EnsureSpace ensure_space(this);
499
+ EMIT(0x88);
500
+ emit_operand(src, dst);
501
+ }
502
+
503
+
504
+ void Assembler::mov_w(Register dst, const Operand& src) {
505
+ EnsureSpace ensure_space(this);
506
+ EMIT(0x66);
507
+ EMIT(0x8B);
508
+ emit_operand(dst, src);
509
+ }
510
+
511
+
512
+ void Assembler::mov_w(const Operand& dst, Register src) {
513
+ EnsureSpace ensure_space(this);
514
+ EMIT(0x66);
515
+ EMIT(0x89);
516
+ emit_operand(src, dst);
517
+ }
518
+
519
+
520
+ void Assembler::mov(Register dst, int32_t imm32) {
521
+ EnsureSpace ensure_space(this);
522
+ EMIT(0xB8 | dst.code());
523
+ emit(imm32);
524
+ }
525
+
526
+
527
+ void Assembler::mov(Register dst, const Immediate& x) {
528
+ EnsureSpace ensure_space(this);
529
+ EMIT(0xB8 | dst.code());
530
+ emit(x);
531
+ }
532
+
533
+
534
+ void Assembler::mov(Register dst, Handle<Object> handle) {
535
+ EnsureSpace ensure_space(this);
536
+ EMIT(0xB8 | dst.code());
537
+ emit(handle);
538
+ }
539
+
540
+
541
+ void Assembler::mov(Register dst, const Operand& src) {
542
+ EnsureSpace ensure_space(this);
543
+ EMIT(0x8B);
544
+ emit_operand(dst, src);
545
+ }
546
+
547
+
548
+ void Assembler::mov(Register dst, Register src) {
549
+ EnsureSpace ensure_space(this);
550
+ EMIT(0x89);
551
+ EMIT(0xC0 | src.code() << 3 | dst.code());
552
+ }
553
+
554
+
555
+ void Assembler::mov(const Operand& dst, const Immediate& x) {
556
+ EnsureSpace ensure_space(this);
557
+ EMIT(0xC7);
558
+ emit_operand(eax, dst);
559
+ emit(x);
560
+ }
561
+
562
+
563
+ void Assembler::mov(const Operand& dst, Handle<Object> handle) {
564
+ EnsureSpace ensure_space(this);
565
+ EMIT(0xC7);
566
+ emit_operand(eax, dst);
567
+ emit(handle);
568
+ }
569
+
570
+
571
+ void Assembler::mov(const Operand& dst, Register src) {
572
+ EnsureSpace ensure_space(this);
573
+ EMIT(0x89);
574
+ emit_operand(src, dst);
575
+ }
576
+
577
+
578
+ void Assembler::movsx_b(Register dst, const Operand& src) {
579
+ EnsureSpace ensure_space(this);
580
+ EMIT(0x0F);
581
+ EMIT(0xBE);
582
+ emit_operand(dst, src);
583
+ }
584
+
585
+
586
+ void Assembler::movsx_w(Register dst, const Operand& src) {
587
+ EnsureSpace ensure_space(this);
588
+ EMIT(0x0F);
589
+ EMIT(0xBF);
590
+ emit_operand(dst, src);
591
+ }
592
+
593
+
594
+ void Assembler::movzx_b(Register dst, const Operand& src) {
595
+ EnsureSpace ensure_space(this);
596
+ EMIT(0x0F);
597
+ EMIT(0xB6);
598
+ emit_operand(dst, src);
599
+ }
600
+
601
+
602
+ void Assembler::movzx_w(Register dst, const Operand& src) {
603
+ EnsureSpace ensure_space(this);
604
+ EMIT(0x0F);
605
+ EMIT(0xB7);
606
+ emit_operand(dst, src);
607
+ }
608
+
609
+
610
+ void Assembler::cmov(Condition cc, Register dst, int32_t imm32) {
611
+ ASSERT(CpuFeatures::IsEnabled(CMOV));
612
+ EnsureSpace ensure_space(this);
613
+ UNIMPLEMENTED();
614
+ USE(cc);
615
+ USE(dst);
616
+ USE(imm32);
617
+ }
618
+
619
+
620
+ void Assembler::cmov(Condition cc, Register dst, Handle<Object> handle) {
621
+ ASSERT(CpuFeatures::IsEnabled(CMOV));
622
+ EnsureSpace ensure_space(this);
623
+ UNIMPLEMENTED();
624
+ USE(cc);
625
+ USE(dst);
626
+ USE(handle);
627
+ }
628
+
629
+
630
+ void Assembler::cmov(Condition cc, Register dst, const Operand& src) {
631
+ ASSERT(CpuFeatures::IsEnabled(CMOV));
632
+ EnsureSpace ensure_space(this);
633
+ // Opcode: 0f 40 + cc /r.
634
+ EMIT(0x0F);
635
+ EMIT(0x40 + cc);
636
+ emit_operand(dst, src);
637
+ }
638
+
639
+
640
+ void Assembler::cld() {
641
+ EnsureSpace ensure_space(this);
642
+ EMIT(0xFC);
643
+ }
644
+
645
+
646
+ void Assembler::rep_movs() {
647
+ EnsureSpace ensure_space(this);
648
+ EMIT(0xF3);
649
+ EMIT(0xA5);
650
+ }
651
+
652
+
653
+ void Assembler::rep_stos() {
654
+ EnsureSpace ensure_space(this);
655
+ EMIT(0xF3);
656
+ EMIT(0xAB);
657
+ }
658
+
659
+
660
+ void Assembler::stos() {
661
+ EnsureSpace ensure_space(this);
662
+ EMIT(0xAB);
663
+ }
664
+
665
+
666
+ void Assembler::xchg(Register dst, Register src) {
667
+ EnsureSpace ensure_space(this);
668
+ if (src.is(eax) || dst.is(eax)) { // Single-byte encoding.
669
+ EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
670
+ } else {
671
+ EMIT(0x87);
672
+ EMIT(0xC0 | src.code() << 3 | dst.code());
673
+ }
674
+ }
675
+
676
+
677
+ void Assembler::adc(Register dst, int32_t imm32) {
678
+ EnsureSpace ensure_space(this);
679
+ emit_arith(2, Operand(dst), Immediate(imm32));
680
+ }
681
+
682
+
683
+ void Assembler::adc(Register dst, const Operand& src) {
684
+ EnsureSpace ensure_space(this);
685
+ EMIT(0x13);
686
+ emit_operand(dst, src);
687
+ }
688
+
689
+
690
+ void Assembler::add(Register dst, const Operand& src) {
691
+ EnsureSpace ensure_space(this);
692
+ EMIT(0x03);
693
+ emit_operand(dst, src);
694
+ }
695
+
696
+
697
+ void Assembler::add(const Operand& dst, const Immediate& x) {
698
+ ASSERT(reloc_info_writer.last_pc() != NULL);
699
+ EnsureSpace ensure_space(this);
700
+ emit_arith(0, dst, x);
701
+ }
702
+
703
+
704
+ void Assembler::and_(Register dst, int32_t imm32) {
705
+ and_(dst, Immediate(imm32));
706
+ }
707
+
708
+
709
+ void Assembler::and_(Register dst, const Immediate& x) {
710
+ EnsureSpace ensure_space(this);
711
+ emit_arith(4, Operand(dst), x);
712
+ }
713
+
714
+
715
+ void Assembler::and_(Register dst, const Operand& src) {
716
+ EnsureSpace ensure_space(this);
717
+ EMIT(0x23);
718
+ emit_operand(dst, src);
719
+ }
720
+
721
+
722
+ void Assembler::and_(const Operand& dst, const Immediate& x) {
723
+ EnsureSpace ensure_space(this);
724
+ emit_arith(4, dst, x);
725
+ }
726
+
727
+
728
+ void Assembler::and_(const Operand& dst, Register src) {
729
+ EnsureSpace ensure_space(this);
730
+ EMIT(0x21);
731
+ emit_operand(src, dst);
732
+ }
733
+
734
+
735
+ void Assembler::cmpb(const Operand& op, int8_t imm8) {
736
+ EnsureSpace ensure_space(this);
737
+ EMIT(0x80);
738
+ emit_operand(edi, op); // edi == 7
739
+ EMIT(imm8);
740
+ }
741
+
742
+
743
+ void Assembler::cmpb(const Operand& dst, Register src) {
744
+ ASSERT(src.is_byte_register());
745
+ EnsureSpace ensure_space(this);
746
+ EMIT(0x38);
747
+ emit_operand(src, dst);
748
+ }
749
+
750
+
751
+ void Assembler::cmpb(Register dst, const Operand& src) {
752
+ ASSERT(dst.is_byte_register());
753
+ EnsureSpace ensure_space(this);
754
+ EMIT(0x3A);
755
+ emit_operand(dst, src);
756
+ }
757
+
758
+
759
+ void Assembler::cmpw(const Operand& op, Immediate imm16) {
760
+ ASSERT(imm16.is_int16());
761
+ EnsureSpace ensure_space(this);
762
+ EMIT(0x66);
763
+ EMIT(0x81);
764
+ emit_operand(edi, op);
765
+ emit_w(imm16);
766
+ }
767
+
768
+
769
+ void Assembler::cmp(Register reg, int32_t imm32) {
770
+ EnsureSpace ensure_space(this);
771
+ emit_arith(7, Operand(reg), Immediate(imm32));
772
+ }
773
+
774
+
775
+ void Assembler::cmp(Register reg, Handle<Object> handle) {
776
+ EnsureSpace ensure_space(this);
777
+ emit_arith(7, Operand(reg), Immediate(handle));
778
+ }
779
+
780
+
781
+ void Assembler::cmp(Register reg, const Operand& op) {
782
+ EnsureSpace ensure_space(this);
783
+ EMIT(0x3B);
784
+ emit_operand(reg, op);
785
+ }
786
+
787
+
788
+ void Assembler::cmp(const Operand& op, const Immediate& imm) {
789
+ EnsureSpace ensure_space(this);
790
+ emit_arith(7, op, imm);
791
+ }
792
+
793
+
794
+ void Assembler::cmp(const Operand& op, Handle<Object> handle) {
795
+ EnsureSpace ensure_space(this);
796
+ emit_arith(7, op, Immediate(handle));
797
+ }
798
+
799
+
800
+ void Assembler::cmpb_al(const Operand& op) {
801
+ EnsureSpace ensure_space(this);
802
+ EMIT(0x38); // CMP r/m8, r8
803
+ emit_operand(eax, op); // eax has same code as register al.
804
+ }
805
+
806
+
807
+ void Assembler::cmpw_ax(const Operand& op) {
808
+ EnsureSpace ensure_space(this);
809
+ EMIT(0x66);
810
+ EMIT(0x39); // CMP r/m16, r16
811
+ emit_operand(eax, op); // eax has same code as register ax.
812
+ }
813
+
814
+
815
+ void Assembler::dec_b(Register dst) {
816
+ EnsureSpace ensure_space(this);
817
+ EMIT(0xFE);
818
+ EMIT(0xC8 | dst.code());
819
+ }
820
+
821
+
822
+ void Assembler::dec_b(const Operand& dst) {
823
+ EnsureSpace ensure_space(this);
824
+ EMIT(0xFE);
825
+ emit_operand(ecx, dst);
826
+ }
827
+
828
+
829
+ void Assembler::dec(Register dst) {
830
+ EnsureSpace ensure_space(this);
831
+ EMIT(0x48 | dst.code());
832
+ }
833
+
834
+
835
+ void Assembler::dec(const Operand& dst) {
836
+ EnsureSpace ensure_space(this);
837
+ EMIT(0xFF);
838
+ emit_operand(ecx, dst);
839
+ }
840
+
841
+
842
+ void Assembler::cdq() {
843
+ EnsureSpace ensure_space(this);
844
+ EMIT(0x99);
845
+ }
846
+
847
+
848
+ void Assembler::idiv(Register src) {
849
+ EnsureSpace ensure_space(this);
850
+ EMIT(0xF7);
851
+ EMIT(0xF8 | src.code());
852
+ }
853
+
854
+
855
+ void Assembler::imul(Register reg) {
856
+ EnsureSpace ensure_space(this);
857
+ EMIT(0xF7);
858
+ EMIT(0xE8 | reg.code());
859
+ }
860
+
861
+
862
+ void Assembler::imul(Register dst, const Operand& src) {
863
+ EnsureSpace ensure_space(this);
864
+ EMIT(0x0F);
865
+ EMIT(0xAF);
866
+ emit_operand(dst, src);
867
+ }
868
+
869
+
870
+ void Assembler::imul(Register dst, Register src, int32_t imm32) {
871
+ EnsureSpace ensure_space(this);
872
+ if (is_int8(imm32)) {
873
+ EMIT(0x6B);
874
+ EMIT(0xC0 | dst.code() << 3 | src.code());
875
+ EMIT(imm32);
876
+ } else {
877
+ EMIT(0x69);
878
+ EMIT(0xC0 | dst.code() << 3 | src.code());
879
+ emit(imm32);
880
+ }
881
+ }
882
+
883
+
884
+ void Assembler::inc(Register dst) {
885
+ EnsureSpace ensure_space(this);
886
+ EMIT(0x40 | dst.code());
887
+ }
888
+
889
+
890
+ void Assembler::inc(const Operand& dst) {
891
+ EnsureSpace ensure_space(this);
892
+ EMIT(0xFF);
893
+ emit_operand(eax, dst);
894
+ }
895
+
896
+
897
+ void Assembler::lea(Register dst, const Operand& src) {
898
+ EnsureSpace ensure_space(this);
899
+ EMIT(0x8D);
900
+ emit_operand(dst, src);
901
+ }
902
+
903
+
904
+ void Assembler::mul(Register src) {
905
+ EnsureSpace ensure_space(this);
906
+ EMIT(0xF7);
907
+ EMIT(0xE0 | src.code());
908
+ }
909
+
910
+
911
+ void Assembler::neg(Register dst) {
912
+ EnsureSpace ensure_space(this);
913
+ EMIT(0xF7);
914
+ EMIT(0xD8 | dst.code());
915
+ }
916
+
917
+
918
+ void Assembler::not_(Register dst) {
919
+ EnsureSpace ensure_space(this);
920
+ EMIT(0xF7);
921
+ EMIT(0xD0 | dst.code());
922
+ }
923
+
924
+
925
+ void Assembler::or_(Register dst, int32_t imm32) {
926
+ EnsureSpace ensure_space(this);
927
+ emit_arith(1, Operand(dst), Immediate(imm32));
928
+ }
929
+
930
+
931
+ void Assembler::or_(Register dst, const Operand& src) {
932
+ EnsureSpace ensure_space(this);
933
+ EMIT(0x0B);
934
+ emit_operand(dst, src);
935
+ }
936
+
937
+
938
+ void Assembler::or_(const Operand& dst, const Immediate& x) {
939
+ EnsureSpace ensure_space(this);
940
+ emit_arith(1, dst, x);
941
+ }
942
+
943
+
944
+ void Assembler::or_(const Operand& dst, Register src) {
945
+ EnsureSpace ensure_space(this);
946
+ EMIT(0x09);
947
+ emit_operand(src, dst);
948
+ }
949
+
950
+
951
+ void Assembler::rcl(Register dst, uint8_t imm8) {
952
+ EnsureSpace ensure_space(this);
953
+ ASSERT(is_uint5(imm8)); // illegal shift count
954
+ if (imm8 == 1) {
955
+ EMIT(0xD1);
956
+ EMIT(0xD0 | dst.code());
957
+ } else {
958
+ EMIT(0xC1);
959
+ EMIT(0xD0 | dst.code());
960
+ EMIT(imm8);
961
+ }
962
+ }
963
+
964
+
965
+ void Assembler::rcr(Register dst, uint8_t imm8) {
966
+ EnsureSpace ensure_space(this);
967
+ ASSERT(is_uint5(imm8)); // illegal shift count
968
+ if (imm8 == 1) {
969
+ EMIT(0xD1);
970
+ EMIT(0xD8 | dst.code());
971
+ } else {
972
+ EMIT(0xC1);
973
+ EMIT(0xD8 | dst.code());
974
+ EMIT(imm8);
975
+ }
976
+ }
977
+
978
+
979
+ void Assembler::sar(Register dst, uint8_t imm8) {
980
+ EnsureSpace ensure_space(this);
981
+ ASSERT(is_uint5(imm8)); // illegal shift count
982
+ if (imm8 == 1) {
983
+ EMIT(0xD1);
984
+ EMIT(0xF8 | dst.code());
985
+ } else {
986
+ EMIT(0xC1);
987
+ EMIT(0xF8 | dst.code());
988
+ EMIT(imm8);
989
+ }
990
+ }
991
+
992
+
993
+ void Assembler::sar_cl(Register dst) {
994
+ EnsureSpace ensure_space(this);
995
+ EMIT(0xD3);
996
+ EMIT(0xF8 | dst.code());
997
+ }
998
+
999
+
1000
+ void Assembler::sbb(Register dst, const Operand& src) {
1001
+ EnsureSpace ensure_space(this);
1002
+ EMIT(0x1B);
1003
+ emit_operand(dst, src);
1004
+ }
1005
+
1006
+
1007
+ void Assembler::shld(Register dst, const Operand& src) {
1008
+ EnsureSpace ensure_space(this);
1009
+ EMIT(0x0F);
1010
+ EMIT(0xA5);
1011
+ emit_operand(dst, src);
1012
+ }
1013
+
1014
+
1015
+ void Assembler::shl(Register dst, uint8_t imm8) {
1016
+ EnsureSpace ensure_space(this);
1017
+ ASSERT(is_uint5(imm8)); // illegal shift count
1018
+ if (imm8 == 1) {
1019
+ EMIT(0xD1);
1020
+ EMIT(0xE0 | dst.code());
1021
+ } else {
1022
+ EMIT(0xC1);
1023
+ EMIT(0xE0 | dst.code());
1024
+ EMIT(imm8);
1025
+ }
1026
+ }
1027
+
1028
+
1029
+ void Assembler::shl_cl(Register dst) {
1030
+ EnsureSpace ensure_space(this);
1031
+ EMIT(0xD3);
1032
+ EMIT(0xE0 | dst.code());
1033
+ }
1034
+
1035
+
1036
+ void Assembler::shrd(Register dst, const Operand& src) {
1037
+ EnsureSpace ensure_space(this);
1038
+ EMIT(0x0F);
1039
+ EMIT(0xAD);
1040
+ emit_operand(dst, src);
1041
+ }
1042
+
1043
+
1044
+ void Assembler::shr(Register dst, uint8_t imm8) {
1045
+ EnsureSpace ensure_space(this);
1046
+ ASSERT(is_uint5(imm8)); // illegal shift count
1047
+ if (imm8 == 1) {
1048
+ EMIT(0xD1);
1049
+ EMIT(0xE8 | dst.code());
1050
+ } else {
1051
+ EMIT(0xC1);
1052
+ EMIT(0xE8 | dst.code());
1053
+ EMIT(imm8);
1054
+ }
1055
+ }
1056
+
1057
+
1058
+ void Assembler::shr_cl(Register dst) {
1059
+ EnsureSpace ensure_space(this);
1060
+ EMIT(0xD3);
1061
+ EMIT(0xE8 | dst.code());
1062
+ }
1063
+
1064
+
1065
+ void Assembler::subb(const Operand& op, int8_t imm8) {
1066
+ EnsureSpace ensure_space(this);
1067
+ if (op.is_reg(eax)) {
1068
+ EMIT(0x2c);
1069
+ } else {
1070
+ EMIT(0x80);
1071
+ emit_operand(ebp, op); // ebp == 5
1072
+ }
1073
+ EMIT(imm8);
1074
+ }
1075
+
1076
+
1077
+ void Assembler::sub(const Operand& dst, const Immediate& x) {
1078
+ EnsureSpace ensure_space(this);
1079
+ emit_arith(5, dst, x);
1080
+ }
1081
+
1082
+
1083
+ void Assembler::sub(Register dst, const Operand& src) {
1084
+ EnsureSpace ensure_space(this);
1085
+ EMIT(0x2B);
1086
+ emit_operand(dst, src);
1087
+ }
1088
+
1089
+
1090
+ void Assembler::subb(Register dst, const Operand& src) {
1091
+ ASSERT(dst.code() < 4);
1092
+ EnsureSpace ensure_space(this);
1093
+ EMIT(0x2A);
1094
+ emit_operand(dst, src);
1095
+ }
1096
+
1097
+
1098
+ void Assembler::sub(const Operand& dst, Register src) {
1099
+ EnsureSpace ensure_space(this);
1100
+ EMIT(0x29);
1101
+ emit_operand(src, dst);
1102
+ }
1103
+
1104
+
1105
+ void Assembler::test(Register reg, const Immediate& imm) {
1106
+ EnsureSpace ensure_space(this);
1107
+ // Only use test against byte for registers that have a byte
1108
+ // variant: eax, ebx, ecx, and edx.
1109
+ if (imm.rmode_ == RelocInfo::NONE && is_uint8(imm.x_) && reg.code() < 4) {
1110
+ uint8_t imm8 = imm.x_;
1111
+ if (reg.is(eax)) {
1112
+ EMIT(0xA8);
1113
+ EMIT(imm8);
1114
+ } else {
1115
+ emit_arith_b(0xF6, 0xC0, reg, imm8);
1116
+ }
1117
+ } else {
1118
+ // This is not using emit_arith because test doesn't support
1119
+ // sign-extension of 8-bit operands.
1120
+ if (reg.is(eax)) {
1121
+ EMIT(0xA9);
1122
+ } else {
1123
+ EMIT(0xF7);
1124
+ EMIT(0xC0 | reg.code());
1125
+ }
1126
+ emit(imm);
1127
+ }
1128
+ }
1129
+
1130
+
1131
+ void Assembler::test(Register reg, const Operand& op) {
1132
+ EnsureSpace ensure_space(this);
1133
+ EMIT(0x85);
1134
+ emit_operand(reg, op);
1135
+ }
1136
+
1137
+
1138
+ void Assembler::test_b(Register reg, const Operand& op) {
1139
+ EnsureSpace ensure_space(this);
1140
+ EMIT(0x84);
1141
+ emit_operand(reg, op);
1142
+ }
1143
+
1144
+
1145
+ void Assembler::test(const Operand& op, const Immediate& imm) {
1146
+ EnsureSpace ensure_space(this);
1147
+ EMIT(0xF7);
1148
+ emit_operand(eax, op);
1149
+ emit(imm);
1150
+ }
1151
+
1152
+
1153
+ void Assembler::test_b(const Operand& op, uint8_t imm8) {
1154
+ EnsureSpace ensure_space(this);
1155
+ EMIT(0xF6);
1156
+ emit_operand(eax, op);
1157
+ EMIT(imm8);
1158
+ }
1159
+
1160
+
1161
+ void Assembler::xor_(Register dst, int32_t imm32) {
1162
+ EnsureSpace ensure_space(this);
1163
+ emit_arith(6, Operand(dst), Immediate(imm32));
1164
+ }
1165
+
1166
+
1167
+ void Assembler::xor_(Register dst, const Operand& src) {
1168
+ EnsureSpace ensure_space(this);
1169
+ EMIT(0x33);
1170
+ emit_operand(dst, src);
1171
+ }
1172
+
1173
+
1174
+ void Assembler::xor_(const Operand& src, Register dst) {
1175
+ EnsureSpace ensure_space(this);
1176
+ EMIT(0x31);
1177
+ emit_operand(dst, src);
1178
+ }
1179
+
1180
+
1181
+ void Assembler::xor_(const Operand& dst, const Immediate& x) {
1182
+ EnsureSpace ensure_space(this);
1183
+ emit_arith(6, dst, x);
1184
+ }
1185
+
1186
+
1187
+ void Assembler::bt(const Operand& dst, Register src) {
1188
+ EnsureSpace ensure_space(this);
1189
+ EMIT(0x0F);
1190
+ EMIT(0xA3);
1191
+ emit_operand(src, dst);
1192
+ }
1193
+
1194
+
1195
+ void Assembler::bts(const Operand& dst, Register src) {
1196
+ EnsureSpace ensure_space(this);
1197
+ EMIT(0x0F);
1198
+ EMIT(0xAB);
1199
+ emit_operand(src, dst);
1200
+ }
1201
+
1202
+
1203
+ void Assembler::hlt() {
1204
+ EnsureSpace ensure_space(this);
1205
+ EMIT(0xF4);
1206
+ }
1207
+
1208
+
1209
+ void Assembler::int3() {
1210
+ EnsureSpace ensure_space(this);
1211
+ EMIT(0xCC);
1212
+ }
1213
+
1214
+
1215
+ void Assembler::nop() {
1216
+ EnsureSpace ensure_space(this);
1217
+ EMIT(0x90);
1218
+ }
1219
+
1220
+
1221
+ void Assembler::rdtsc() {
1222
+ ASSERT(CpuFeatures::IsEnabled(RDTSC));
1223
+ EnsureSpace ensure_space(this);
1224
+ EMIT(0x0F);
1225
+ EMIT(0x31);
1226
+ }
1227
+
1228
+
1229
+ void Assembler::ret(int imm16) {
1230
+ EnsureSpace ensure_space(this);
1231
+ ASSERT(is_uint16(imm16));
1232
+ if (imm16 == 0) {
1233
+ EMIT(0xC3);
1234
+ } else {
1235
+ EMIT(0xC2);
1236
+ EMIT(imm16 & 0xFF);
1237
+ EMIT((imm16 >> 8) & 0xFF);
1238
+ }
1239
+ }
1240
+
1241
+
1242
+ // Labels refer to positions in the (to be) generated code.
1243
+ // There are bound, linked, and unused labels.
1244
+ //
1245
+ // Bound labels refer to known positions in the already
1246
+ // generated code. pos() is the position the label refers to.
1247
+ //
1248
+ // Linked labels refer to unknown positions in the code
1249
+ // to be generated; pos() is the position of the 32bit
1250
+ // Displacement of the last instruction using the label.
1251
+
1252
+
1253
+ void Assembler::print(Label* L) {
1254
+ if (L->is_unused()) {
1255
+ PrintF("unused label\n");
1256
+ } else if (L->is_bound()) {
1257
+ PrintF("bound label to %d\n", L->pos());
1258
+ } else if (L->is_linked()) {
1259
+ Label l = *L;
1260
+ PrintF("unbound label");
1261
+ while (l.is_linked()) {
1262
+ Displacement disp = disp_at(&l);
1263
+ PrintF("@ %d ", l.pos());
1264
+ disp.print();
1265
+ PrintF("\n");
1266
+ disp.next(&l);
1267
+ }
1268
+ } else {
1269
+ PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
1270
+ }
1271
+ }
1272
+
1273
+
1274
+ void Assembler::bind_to(Label* L, int pos) {
1275
+ EnsureSpace ensure_space(this);
1276
+ ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position
1277
+ while (L->is_linked()) {
1278
+ Displacement disp = disp_at(L);
1279
+ int fixup_pos = L->pos();
1280
+ if (disp.type() == Displacement::CODE_RELATIVE) {
1281
+ // Relative to Code* heap object pointer.
1282
+ long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1283
+ } else {
1284
+ if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1285
+ ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected
1286
+ }
1287
+ // Relative address, relative to point after address.
1288
+ int imm32 = pos - (fixup_pos + sizeof(int32_t));
1289
+ long_at_put(fixup_pos, imm32);
1290
+ }
1291
+ disp.next(L);
1292
+ }
1293
+ while (L->is_near_linked()) {
1294
+ int fixup_pos = L->near_link_pos();
1295
+ int offset_to_next =
1296
+ static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
1297
+ ASSERT(offset_to_next <= 0);
1298
+ // Relative address, relative to point after address.
1299
+ int disp = pos - fixup_pos - sizeof(int8_t);
1300
+ ASSERT(0 <= disp && disp <= 127);
1301
+ set_byte_at(fixup_pos, disp);
1302
+ if (offset_to_next < 0) {
1303
+ L->link_to(fixup_pos + offset_to_next, Label::kNear);
1304
+ } else {
1305
+ L->UnuseNear();
1306
+ }
1307
+ }
1308
+ L->bind_to(pos);
1309
+ }
1310
+
1311
+
1312
+ void Assembler::bind(Label* L) {
1313
+ EnsureSpace ensure_space(this);
1314
+ ASSERT(!L->is_bound()); // label can only be bound once
1315
+ bind_to(L, pc_offset());
1316
+ }
1317
+
1318
+
1319
+ void Assembler::call(Label* L) {
1320
+ positions_recorder()->WriteRecordedPositions();
1321
+ EnsureSpace ensure_space(this);
1322
+ if (L->is_bound()) {
1323
+ const int long_size = 5;
1324
+ int offs = L->pos() - pc_offset();
1325
+ ASSERT(offs <= 0);
1326
+ // 1110 1000 #32-bit disp.
1327
+ EMIT(0xE8);
1328
+ emit(offs - long_size);
1329
+ } else {
1330
+ // 1110 1000 #32-bit disp.
1331
+ EMIT(0xE8);
1332
+ emit_disp(L, Displacement::OTHER);
1333
+ }
1334
+ }
1335
+
1336
+
1337
+ void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
1338
+ positions_recorder()->WriteRecordedPositions();
1339
+ EnsureSpace ensure_space(this);
1340
+ ASSERT(!RelocInfo::IsCodeTarget(rmode));
1341
+ EMIT(0xE8);
1342
+ emit(entry - (pc_ + sizeof(int32_t)), rmode);
1343
+ }
1344
+
1345
+
1346
+ int Assembler::CallSize(const Operand& adr) {
1347
+ // Call size is 1 (opcode) + adr.len_ (operand).
1348
+ return 1 + adr.len_;
1349
+ }
1350
+
1351
+
1352
+ void Assembler::call(const Operand& adr) {
1353
+ positions_recorder()->WriteRecordedPositions();
1354
+ EnsureSpace ensure_space(this);
1355
+ EMIT(0xFF);
1356
+ emit_operand(edx, adr);
1357
+ }
1358
+
1359
+
1360
+ int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
1361
+ return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
1362
+ }
1363
+
1364
+
1365
+ void Assembler::call(Handle<Code> code,
1366
+ RelocInfo::Mode rmode,
1367
+ unsigned ast_id) {
1368
+ positions_recorder()->WriteRecordedPositions();
1369
+ EnsureSpace ensure_space(this);
1370
+ ASSERT(RelocInfo::IsCodeTarget(rmode));
1371
+ EMIT(0xE8);
1372
+ emit(reinterpret_cast<intptr_t>(code.location()), rmode, ast_id);
1373
+ }
1374
+
1375
+
1376
+ void Assembler::jmp(Label* L, Label::Distance distance) {
1377
+ EnsureSpace ensure_space(this);
1378
+ if (L->is_bound()) {
1379
+ const int short_size = 2;
1380
+ const int long_size = 5;
1381
+ int offs = L->pos() - pc_offset();
1382
+ ASSERT(offs <= 0);
1383
+ if (is_int8(offs - short_size)) {
1384
+ // 1110 1011 #8-bit disp.
1385
+ EMIT(0xEB);
1386
+ EMIT((offs - short_size) & 0xFF);
1387
+ } else {
1388
+ // 1110 1001 #32-bit disp.
1389
+ EMIT(0xE9);
1390
+ emit(offs - long_size);
1391
+ }
1392
+ } else if (distance == Label::kNear) {
1393
+ EMIT(0xEB);
1394
+ emit_near_disp(L);
1395
+ } else {
1396
+ // 1110 1001 #32-bit disp.
1397
+ EMIT(0xE9);
1398
+ emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1399
+ }
1400
+ }
1401
+
1402
+
1403
+ void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
1404
+ EnsureSpace ensure_space(this);
1405
+ ASSERT(!RelocInfo::IsCodeTarget(rmode));
1406
+ EMIT(0xE9);
1407
+ emit(entry - (pc_ + sizeof(int32_t)), rmode);
1408
+ }
1409
+
1410
+
1411
+ void Assembler::jmp(const Operand& adr) {
1412
+ EnsureSpace ensure_space(this);
1413
+ EMIT(0xFF);
1414
+ emit_operand(esp, adr);
1415
+ }
1416
+
1417
+
1418
+ void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
1419
+ EnsureSpace ensure_space(this);
1420
+ ASSERT(RelocInfo::IsCodeTarget(rmode));
1421
+ EMIT(0xE9);
1422
+ emit(reinterpret_cast<intptr_t>(code.location()), rmode);
1423
+ }
1424
+
1425
+
1426
+ void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1427
+ EnsureSpace ensure_space(this);
1428
+ ASSERT(0 <= cc && cc < 16);
1429
+ if (L->is_bound()) {
1430
+ const int short_size = 2;
1431
+ const int long_size = 6;
1432
+ int offs = L->pos() - pc_offset();
1433
+ ASSERT(offs <= 0);
1434
+ if (is_int8(offs - short_size)) {
1435
+ // 0111 tttn #8-bit disp
1436
+ EMIT(0x70 | cc);
1437
+ EMIT((offs - short_size) & 0xFF);
1438
+ } else {
1439
+ // 0000 1111 1000 tttn #32-bit disp
1440
+ EMIT(0x0F);
1441
+ EMIT(0x80 | cc);
1442
+ emit(offs - long_size);
1443
+ }
1444
+ } else if (distance == Label::kNear) {
1445
+ EMIT(0x70 | cc);
1446
+ emit_near_disp(L);
1447
+ } else {
1448
+ // 0000 1111 1000 tttn #32-bit disp
1449
+ // Note: could eliminate cond. jumps to this jump if condition
1450
+ // is the same however, seems to be rather unlikely case.
1451
+ EMIT(0x0F);
1452
+ EMIT(0x80 | cc);
1453
+ emit_disp(L, Displacement::OTHER);
1454
+ }
1455
+ }
1456
+
1457
+
1458
+ void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
1459
+ EnsureSpace ensure_space(this);
1460
+ ASSERT((0 <= cc) && (cc < 16));
1461
+ // 0000 1111 1000 tttn #32-bit disp.
1462
+ EMIT(0x0F);
1463
+ EMIT(0x80 | cc);
1464
+ emit(entry - (pc_ + sizeof(int32_t)), rmode);
1465
+ }
1466
+
1467
+
1468
+ void Assembler::j(Condition cc, Handle<Code> code) {
1469
+ EnsureSpace ensure_space(this);
1470
+ // 0000 1111 1000 tttn #32-bit disp
1471
+ EMIT(0x0F);
1472
+ EMIT(0x80 | cc);
1473
+ emit(reinterpret_cast<intptr_t>(code.location()), RelocInfo::CODE_TARGET);
1474
+ }
1475
+
1476
+
1477
+ // FPU instructions.
1478
+
1479
+ void Assembler::fld(int i) {
1480
+ EnsureSpace ensure_space(this);
1481
+ emit_farith(0xD9, 0xC0, i);
1482
+ }
1483
+
1484
+
1485
+ void Assembler::fstp(int i) {
1486
+ EnsureSpace ensure_space(this);
1487
+ emit_farith(0xDD, 0xD8, i);
1488
+ }
1489
+
1490
+
1491
+ void Assembler::fld1() {
1492
+ EnsureSpace ensure_space(this);
1493
+ EMIT(0xD9);
1494
+ EMIT(0xE8);
1495
+ }
1496
+
1497
+
1498
+ void Assembler::fldpi() {
1499
+ EnsureSpace ensure_space(this);
1500
+ EMIT(0xD9);
1501
+ EMIT(0xEB);
1502
+ }
1503
+
1504
+
1505
+ void Assembler::fldz() {
1506
+ EnsureSpace ensure_space(this);
1507
+ EMIT(0xD9);
1508
+ EMIT(0xEE);
1509
+ }
1510
+
1511
+
1512
+ void Assembler::fldln2() {
1513
+ EnsureSpace ensure_space(this);
1514
+ EMIT(0xD9);
1515
+ EMIT(0xED);
1516
+ }
1517
+
1518
+
1519
+ void Assembler::fld_s(const Operand& adr) {
1520
+ EnsureSpace ensure_space(this);
1521
+ EMIT(0xD9);
1522
+ emit_operand(eax, adr);
1523
+ }
1524
+
1525
+
1526
+ void Assembler::fld_d(const Operand& adr) {
1527
+ EnsureSpace ensure_space(this);
1528
+ EMIT(0xDD);
1529
+ emit_operand(eax, adr);
1530
+ }
1531
+
1532
+
1533
+ void Assembler::fstp_s(const Operand& adr) {
1534
+ EnsureSpace ensure_space(this);
1535
+ EMIT(0xD9);
1536
+ emit_operand(ebx, adr);
1537
+ }
1538
+
1539
+
1540
+ void Assembler::fstp_d(const Operand& adr) {
1541
+ EnsureSpace ensure_space(this);
1542
+ EMIT(0xDD);
1543
+ emit_operand(ebx, adr);
1544
+ }
1545
+
1546
+
1547
+ void Assembler::fst_d(const Operand& adr) {
1548
+ EnsureSpace ensure_space(this);
1549
+ EMIT(0xDD);
1550
+ emit_operand(edx, adr);
1551
+ }
1552
+
1553
+
1554
+ void Assembler::fild_s(const Operand& adr) {
1555
+ EnsureSpace ensure_space(this);
1556
+ EMIT(0xDB);
1557
+ emit_operand(eax, adr);
1558
+ }
1559
+
1560
+
1561
+ void Assembler::fild_d(const Operand& adr) {
1562
+ EnsureSpace ensure_space(this);
1563
+ EMIT(0xDF);
1564
+ emit_operand(ebp, adr);
1565
+ }
1566
+
1567
+
1568
+ void Assembler::fistp_s(const Operand& adr) {
1569
+ EnsureSpace ensure_space(this);
1570
+ EMIT(0xDB);
1571
+ emit_operand(ebx, adr);
1572
+ }
1573
+
1574
+
1575
+ void Assembler::fisttp_s(const Operand& adr) {
1576
+ ASSERT(CpuFeatures::IsEnabled(SSE3));
1577
+ EnsureSpace ensure_space(this);
1578
+ EMIT(0xDB);
1579
+ emit_operand(ecx, adr);
1580
+ }
1581
+
1582
+
1583
+ void Assembler::fisttp_d(const Operand& adr) {
1584
+ ASSERT(CpuFeatures::IsEnabled(SSE3));
1585
+ EnsureSpace ensure_space(this);
1586
+ EMIT(0xDD);
1587
+ emit_operand(ecx, adr);
1588
+ }
1589
+
1590
+
1591
+ void Assembler::fist_s(const Operand& adr) {
1592
+ EnsureSpace ensure_space(this);
1593
+ EMIT(0xDB);
1594
+ emit_operand(edx, adr);
1595
+ }
1596
+
1597
+
1598
+ void Assembler::fistp_d(const Operand& adr) {
1599
+ EnsureSpace ensure_space(this);
1600
+ EMIT(0xDF);
1601
+ emit_operand(edi, adr);
1602
+ }
1603
+
1604
+
1605
+ void Assembler::fabs() {
1606
+ EnsureSpace ensure_space(this);
1607
+ EMIT(0xD9);
1608
+ EMIT(0xE1);
1609
+ }
1610
+
1611
+
1612
+ void Assembler::fchs() {
1613
+ EnsureSpace ensure_space(this);
1614
+ EMIT(0xD9);
1615
+ EMIT(0xE0);
1616
+ }
1617
+
1618
+
1619
+ void Assembler::fcos() {
1620
+ EnsureSpace ensure_space(this);
1621
+ EMIT(0xD9);
1622
+ EMIT(0xFF);
1623
+ }
1624
+
1625
+
1626
+ void Assembler::fsin() {
1627
+ EnsureSpace ensure_space(this);
1628
+ EMIT(0xD9);
1629
+ EMIT(0xFE);
1630
+ }
1631
+
1632
+
1633
+ void Assembler::fyl2x() {
1634
+ EnsureSpace ensure_space(this);
1635
+ EMIT(0xD9);
1636
+ EMIT(0xF1);
1637
+ }
1638
+
1639
+
1640
+ void Assembler::fadd(int i) {
1641
+ EnsureSpace ensure_space(this);
1642
+ emit_farith(0xDC, 0xC0, i);
1643
+ }
1644
+
1645
+
1646
+ void Assembler::fsub(int i) {
1647
+ EnsureSpace ensure_space(this);
1648
+ emit_farith(0xDC, 0xE8, i);
1649
+ }
1650
+
1651
+
1652
+ void Assembler::fisub_s(const Operand& adr) {
1653
+ EnsureSpace ensure_space(this);
1654
+ EMIT(0xDA);
1655
+ emit_operand(esp, adr);
1656
+ }
1657
+
1658
+
1659
+ void Assembler::fmul(int i) {
1660
+ EnsureSpace ensure_space(this);
1661
+ emit_farith(0xDC, 0xC8, i);
1662
+ }
1663
+
1664
+
1665
+ void Assembler::fdiv(int i) {
1666
+ EnsureSpace ensure_space(this);
1667
+ emit_farith(0xDC, 0xF8, i);
1668
+ }
1669
+
1670
+
1671
+ void Assembler::faddp(int i) {
1672
+ EnsureSpace ensure_space(this);
1673
+ emit_farith(0xDE, 0xC0, i);
1674
+ }
1675
+
1676
+
1677
+ void Assembler::fsubp(int i) {
1678
+ EnsureSpace ensure_space(this);
1679
+ emit_farith(0xDE, 0xE8, i);
1680
+ }
1681
+
1682
+
1683
+ void Assembler::fsubrp(int i) {
1684
+ EnsureSpace ensure_space(this);
1685
+ emit_farith(0xDE, 0xE0, i);
1686
+ }
1687
+
1688
+
1689
+ void Assembler::fmulp(int i) {
1690
+ EnsureSpace ensure_space(this);
1691
+ emit_farith(0xDE, 0xC8, i);
1692
+ }
1693
+
1694
+
1695
+ void Assembler::fdivp(int i) {
1696
+ EnsureSpace ensure_space(this);
1697
+ emit_farith(0xDE, 0xF8, i);
1698
+ }
1699
+
1700
+
1701
+ void Assembler::fprem() {
1702
+ EnsureSpace ensure_space(this);
1703
+ EMIT(0xD9);
1704
+ EMIT(0xF8);
1705
+ }
1706
+
1707
+
1708
+ void Assembler::fprem1() {
1709
+ EnsureSpace ensure_space(this);
1710
+ EMIT(0xD9);
1711
+ EMIT(0xF5);
1712
+ }
1713
+
1714
+
1715
+ void Assembler::fxch(int i) {
1716
+ EnsureSpace ensure_space(this);
1717
+ emit_farith(0xD9, 0xC8, i);
1718
+ }
1719
+
1720
+
1721
+ void Assembler::fincstp() {
1722
+ EnsureSpace ensure_space(this);
1723
+ EMIT(0xD9);
1724
+ EMIT(0xF7);
1725
+ }
1726
+
1727
+
1728
+ void Assembler::ffree(int i) {
1729
+ EnsureSpace ensure_space(this);
1730
+ emit_farith(0xDD, 0xC0, i);
1731
+ }
1732
+
1733
+
1734
+ void Assembler::ftst() {
1735
+ EnsureSpace ensure_space(this);
1736
+ EMIT(0xD9);
1737
+ EMIT(0xE4);
1738
+ }
1739
+
1740
+
1741
+ void Assembler::fucomp(int i) {
1742
+ EnsureSpace ensure_space(this);
1743
+ emit_farith(0xDD, 0xE8, i);
1744
+ }
1745
+
1746
+
1747
+ void Assembler::fucompp() {
1748
+ EnsureSpace ensure_space(this);
1749
+ EMIT(0xDA);
1750
+ EMIT(0xE9);
1751
+ }
1752
+
1753
+
1754
+ void Assembler::fucomi(int i) {
1755
+ EnsureSpace ensure_space(this);
1756
+ EMIT(0xDB);
1757
+ EMIT(0xE8 + i);
1758
+ }
1759
+
1760
+
1761
+ void Assembler::fucomip() {
1762
+ EnsureSpace ensure_space(this);
1763
+ EMIT(0xDF);
1764
+ EMIT(0xE9);
1765
+ }
1766
+
1767
+
1768
+ void Assembler::fcompp() {
1769
+ EnsureSpace ensure_space(this);
1770
+ EMIT(0xDE);
1771
+ EMIT(0xD9);
1772
+ }
1773
+
1774
+
1775
+ void Assembler::fnstsw_ax() {
1776
+ EnsureSpace ensure_space(this);
1777
+ EMIT(0xDF);
1778
+ EMIT(0xE0);
1779
+ }
1780
+
1781
+
1782
+ void Assembler::fwait() {
1783
+ EnsureSpace ensure_space(this);
1784
+ EMIT(0x9B);
1785
+ }
1786
+
1787
+
1788
+ void Assembler::frndint() {
1789
+ EnsureSpace ensure_space(this);
1790
+ EMIT(0xD9);
1791
+ EMIT(0xFC);
1792
+ }
1793
+
1794
+
1795
+ void Assembler::fnclex() {
1796
+ EnsureSpace ensure_space(this);
1797
+ EMIT(0xDB);
1798
+ EMIT(0xE2);
1799
+ }
1800
+
1801
+
1802
+ void Assembler::sahf() {
1803
+ EnsureSpace ensure_space(this);
1804
+ EMIT(0x9E);
1805
+ }
1806
+
1807
+
1808
+ void Assembler::setcc(Condition cc, Register reg) {
1809
+ ASSERT(reg.is_byte_register());
1810
+ EnsureSpace ensure_space(this);
1811
+ EMIT(0x0F);
1812
+ EMIT(0x90 | cc);
1813
+ EMIT(0xC0 | reg.code());
1814
+ }
1815
+
1816
+
1817
+ void Assembler::cvttss2si(Register dst, const Operand& src) {
1818
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1819
+ EnsureSpace ensure_space(this);
1820
+ EMIT(0xF3);
1821
+ EMIT(0x0F);
1822
+ EMIT(0x2C);
1823
+ emit_operand(dst, src);
1824
+ }
1825
+
1826
+
1827
+ void Assembler::cvttsd2si(Register dst, const Operand& src) {
1828
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1829
+ EnsureSpace ensure_space(this);
1830
+ EMIT(0xF2);
1831
+ EMIT(0x0F);
1832
+ EMIT(0x2C);
1833
+ emit_operand(dst, src);
1834
+ }
1835
+
1836
+
1837
+ void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
1838
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1839
+ EnsureSpace ensure_space(this);
1840
+ EMIT(0xF2);
1841
+ EMIT(0x0F);
1842
+ EMIT(0x2A);
1843
+ emit_sse_operand(dst, src);
1844
+ }
1845
+
1846
+
1847
+ void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
1848
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1849
+ EnsureSpace ensure_space(this);
1850
+ EMIT(0xF3);
1851
+ EMIT(0x0F);
1852
+ EMIT(0x5A);
1853
+ emit_sse_operand(dst, src);
1854
+ }
1855
+
1856
+
1857
+ void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
1858
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1859
+ EnsureSpace ensure_space(this);
1860
+ EMIT(0xF2);
1861
+ EMIT(0x0F);
1862
+ EMIT(0x5A);
1863
+ emit_sse_operand(dst, src);
1864
+ }
1865
+
1866
+
1867
+ void Assembler::addsd(XMMRegister dst, XMMRegister src) {
1868
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1869
+ EnsureSpace ensure_space(this);
1870
+ EMIT(0xF2);
1871
+ EMIT(0x0F);
1872
+ EMIT(0x58);
1873
+ emit_sse_operand(dst, src);
1874
+ }
1875
+
1876
+
1877
+ void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
1878
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1879
+ EnsureSpace ensure_space(this);
1880
+ EMIT(0xF2);
1881
+ EMIT(0x0F);
1882
+ EMIT(0x59);
1883
+ emit_sse_operand(dst, src);
1884
+ }
1885
+
1886
+
1887
+ void Assembler::subsd(XMMRegister dst, XMMRegister src) {
1888
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1889
+ EnsureSpace ensure_space(this);
1890
+ EMIT(0xF2);
1891
+ EMIT(0x0F);
1892
+ EMIT(0x5C);
1893
+ emit_sse_operand(dst, src);
1894
+ }
1895
+
1896
+
1897
+ void Assembler::divsd(XMMRegister dst, XMMRegister src) {
1898
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1899
+ EnsureSpace ensure_space(this);
1900
+ EMIT(0xF2);
1901
+ EMIT(0x0F);
1902
+ EMIT(0x5E);
1903
+ emit_sse_operand(dst, src);
1904
+ }
1905
+
1906
+
1907
+ void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
1908
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1909
+ EnsureSpace ensure_space(this);
1910
+ EMIT(0x66);
1911
+ EMIT(0x0F);
1912
+ EMIT(0x57);
1913
+ emit_sse_operand(dst, src);
1914
+ }
1915
+
1916
+
1917
+ void Assembler::xorps(XMMRegister dst, XMMRegister src) {
1918
+ EnsureSpace ensure_space(this);
1919
+ EMIT(0x0F);
1920
+ EMIT(0x57);
1921
+ emit_sse_operand(dst, src);
1922
+ }
1923
+
1924
+
1925
+ void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
1926
+ EnsureSpace ensure_space(this);
1927
+ EMIT(0xF2);
1928
+ EMIT(0x0F);
1929
+ EMIT(0x51);
1930
+ emit_sse_operand(dst, src);
1931
+ }
1932
+
1933
+
1934
+ void Assembler::andpd(XMMRegister dst, XMMRegister src) {
1935
+ EnsureSpace ensure_space(this);
1936
+ EMIT(0x66);
1937
+ EMIT(0x0F);
1938
+ EMIT(0x54);
1939
+ emit_sse_operand(dst, src);
1940
+ }
1941
+
1942
+
1943
+ void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
1944
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1945
+ EnsureSpace ensure_space(this);
1946
+ EMIT(0x66);
1947
+ EMIT(0x0F);
1948
+ EMIT(0x2E);
1949
+ emit_sse_operand(dst, src);
1950
+ }
1951
+
1952
+
1953
+ void Assembler::movmskpd(Register dst, XMMRegister src) {
1954
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1955
+ EnsureSpace ensure_space(this);
1956
+ EMIT(0x66);
1957
+ EMIT(0x0F);
1958
+ EMIT(0x50);
1959
+ emit_sse_operand(dst, src);
1960
+ }
1961
+
1962
+
1963
+ void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
1964
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1965
+ EnsureSpace ensure_space(this);
1966
+ EMIT(0xF2);
1967
+ EMIT(0x0F);
1968
+ EMIT(0xC2);
1969
+ emit_sse_operand(dst, src);
1970
+ EMIT(1); // LT == 1
1971
+ }
1972
+
1973
+
1974
+ void Assembler::movaps(XMMRegister dst, XMMRegister src) {
1975
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1976
+ EnsureSpace ensure_space(this);
1977
+ EMIT(0x0F);
1978
+ EMIT(0x28);
1979
+ emit_sse_operand(dst, src);
1980
+ }
1981
+
1982
+
1983
+ void Assembler::movdqa(const Operand& dst, XMMRegister src) {
1984
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1985
+ EnsureSpace ensure_space(this);
1986
+ EMIT(0x66);
1987
+ EMIT(0x0F);
1988
+ EMIT(0x7F);
1989
+ emit_sse_operand(src, dst);
1990
+ }
1991
+
1992
+
1993
+ void Assembler::movdqa(XMMRegister dst, const Operand& src) {
1994
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
1995
+ EnsureSpace ensure_space(this);
1996
+ EMIT(0x66);
1997
+ EMIT(0x0F);
1998
+ EMIT(0x6F);
1999
+ emit_sse_operand(dst, src);
2000
+ }
2001
+
2002
+
2003
+ void Assembler::movdqu(const Operand& dst, XMMRegister src ) {
2004
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2005
+ EnsureSpace ensure_space(this);
2006
+ EMIT(0xF3);
2007
+ EMIT(0x0F);
2008
+ EMIT(0x7F);
2009
+ emit_sse_operand(src, dst);
2010
+ }
2011
+
2012
+
2013
+ void Assembler::movdqu(XMMRegister dst, const Operand& src) {
2014
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2015
+ EnsureSpace ensure_space(this);
2016
+ EMIT(0xF3);
2017
+ EMIT(0x0F);
2018
+ EMIT(0x6F);
2019
+ emit_sse_operand(dst, src);
2020
+ }
2021
+
2022
+
2023
+ void Assembler::movntdqa(XMMRegister dst, const Operand& src) {
2024
+ ASSERT(CpuFeatures::IsEnabled(SSE4_1));
2025
+ EnsureSpace ensure_space(this);
2026
+ EMIT(0x66);
2027
+ EMIT(0x0F);
2028
+ EMIT(0x38);
2029
+ EMIT(0x2A);
2030
+ emit_sse_operand(dst, src);
2031
+ }
2032
+
2033
+
2034
+ void Assembler::movntdq(const Operand& dst, XMMRegister src) {
2035
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2036
+ EnsureSpace ensure_space(this);
2037
+ EMIT(0x66);
2038
+ EMIT(0x0F);
2039
+ EMIT(0xE7);
2040
+ emit_sse_operand(src, dst);
2041
+ }
2042
+
2043
+
2044
+ void Assembler::prefetch(const Operand& src, int level) {
2045
+ ASSERT(is_uint2(level));
2046
+ EnsureSpace ensure_space(this);
2047
+ EMIT(0x0F);
2048
+ EMIT(0x18);
2049
+ XMMRegister code = { level }; // Emit hint number in Reg position of RegR/M.
2050
+ emit_sse_operand(code, src);
2051
+ }
2052
+
2053
+
2054
+ void Assembler::movdbl(XMMRegister dst, const Operand& src) {
2055
+ EnsureSpace ensure_space(this);
2056
+ movsd(dst, src);
2057
+ }
2058
+
2059
+
2060
+ void Assembler::movdbl(const Operand& dst, XMMRegister src) {
2061
+ EnsureSpace ensure_space(this);
2062
+ movsd(dst, src);
2063
+ }
2064
+
2065
+
2066
+ void Assembler::movsd(const Operand& dst, XMMRegister src ) {
2067
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2068
+ EnsureSpace ensure_space(this);
2069
+ EMIT(0xF2); // double
2070
+ EMIT(0x0F);
2071
+ EMIT(0x11); // store
2072
+ emit_sse_operand(src, dst);
2073
+ }
2074
+
2075
+
2076
+ void Assembler::movsd(XMMRegister dst, const Operand& src) {
2077
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2078
+ EnsureSpace ensure_space(this);
2079
+ EMIT(0xF2); // double
2080
+ EMIT(0x0F);
2081
+ EMIT(0x10); // load
2082
+ emit_sse_operand(dst, src);
2083
+ }
2084
+
2085
+
2086
+ void Assembler::movsd(XMMRegister dst, XMMRegister src) {
2087
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2088
+ EnsureSpace ensure_space(this);
2089
+ EMIT(0xF2);
2090
+ EMIT(0x0F);
2091
+ EMIT(0x10);
2092
+ emit_sse_operand(dst, src);
2093
+ }
2094
+
2095
+
2096
+ void Assembler::movss(const Operand& dst, XMMRegister src ) {
2097
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2098
+ EnsureSpace ensure_space(this);
2099
+ EMIT(0xF3); // float
2100
+ EMIT(0x0F);
2101
+ EMIT(0x11); // store
2102
+ emit_sse_operand(src, dst);
2103
+ }
2104
+
2105
+
2106
+ void Assembler::movss(XMMRegister dst, const Operand& src) {
2107
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2108
+ EnsureSpace ensure_space(this);
2109
+ EMIT(0xF3); // float
2110
+ EMIT(0x0F);
2111
+ EMIT(0x10); // load
2112
+ emit_sse_operand(dst, src);
2113
+ }
2114
+
2115
+
2116
+ void Assembler::movss(XMMRegister dst, XMMRegister src) {
2117
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2118
+ EnsureSpace ensure_space(this);
2119
+ EMIT(0xF3);
2120
+ EMIT(0x0F);
2121
+ EMIT(0x10);
2122
+ emit_sse_operand(dst, src);
2123
+ }
2124
+
2125
+
2126
+ void Assembler::movd(XMMRegister dst, const Operand& src) {
2127
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2128
+ EnsureSpace ensure_space(this);
2129
+ EMIT(0x66);
2130
+ EMIT(0x0F);
2131
+ EMIT(0x6E);
2132
+ emit_sse_operand(dst, src);
2133
+ }
2134
+
2135
+
2136
+ void Assembler::movd(const Operand& dst, XMMRegister src) {
2137
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2138
+ EnsureSpace ensure_space(this);
2139
+ EMIT(0x66);
2140
+ EMIT(0x0F);
2141
+ EMIT(0x7E);
2142
+ emit_sse_operand(src, dst);
2143
+ }
2144
+
2145
+
2146
+ void Assembler::pand(XMMRegister dst, XMMRegister src) {
2147
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2148
+ EnsureSpace ensure_space(this);
2149
+ EMIT(0x66);
2150
+ EMIT(0x0F);
2151
+ EMIT(0xDB);
2152
+ emit_sse_operand(dst, src);
2153
+ }
2154
+
2155
+
2156
+ void Assembler::pxor(XMMRegister dst, XMMRegister src) {
2157
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2158
+ EnsureSpace ensure_space(this);
2159
+ EMIT(0x66);
2160
+ EMIT(0x0F);
2161
+ EMIT(0xEF);
2162
+ emit_sse_operand(dst, src);
2163
+ }
2164
+
2165
+
2166
+ void Assembler::por(XMMRegister dst, XMMRegister src) {
2167
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2168
+ EnsureSpace ensure_space(this);
2169
+ EMIT(0x66);
2170
+ EMIT(0x0F);
2171
+ EMIT(0xEB);
2172
+ emit_sse_operand(dst, src);
2173
+ }
2174
+
2175
+
2176
+ void Assembler::ptest(XMMRegister dst, XMMRegister src) {
2177
+ ASSERT(CpuFeatures::IsEnabled(SSE4_1));
2178
+ EnsureSpace ensure_space(this);
2179
+ EMIT(0x66);
2180
+ EMIT(0x0F);
2181
+ EMIT(0x38);
2182
+ EMIT(0x17);
2183
+ emit_sse_operand(dst, src);
2184
+ }
2185
+
2186
+
2187
+ void Assembler::psllq(XMMRegister reg, int8_t shift) {
2188
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2189
+ EnsureSpace ensure_space(this);
2190
+ EMIT(0x66);
2191
+ EMIT(0x0F);
2192
+ EMIT(0x73);
2193
+ emit_sse_operand(esi, reg); // esi == 6
2194
+ EMIT(shift);
2195
+ }
2196
+
2197
+
2198
+ void Assembler::psllq(XMMRegister dst, XMMRegister src) {
2199
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2200
+ EnsureSpace ensure_space(this);
2201
+ EMIT(0x66);
2202
+ EMIT(0x0F);
2203
+ EMIT(0xF3);
2204
+ emit_sse_operand(dst, src);
2205
+ }
2206
+
2207
+
2208
+ void Assembler::psrlq(XMMRegister reg, int8_t shift) {
2209
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2210
+ EnsureSpace ensure_space(this);
2211
+ EMIT(0x66);
2212
+ EMIT(0x0F);
2213
+ EMIT(0x73);
2214
+ emit_sse_operand(edx, reg); // edx == 2
2215
+ EMIT(shift);
2216
+ }
2217
+
2218
+
2219
+ void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
2220
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2221
+ EnsureSpace ensure_space(this);
2222
+ EMIT(0x66);
2223
+ EMIT(0x0F);
2224
+ EMIT(0xD3);
2225
+ emit_sse_operand(dst, src);
2226
+ }
2227
+
2228
+
2229
+ void Assembler::pshufd(XMMRegister dst, XMMRegister src, int8_t shuffle) {
2230
+ ASSERT(CpuFeatures::IsEnabled(SSE2));
2231
+ EnsureSpace ensure_space(this);
2232
+ EMIT(0x66);
2233
+ EMIT(0x0F);
2234
+ EMIT(0x70);
2235
+ emit_sse_operand(dst, src);
2236
+ EMIT(shuffle);
2237
+ }
2238
+
2239
+
2240
+ void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) {
2241
+ ASSERT(CpuFeatures::IsEnabled(SSE4_1));
2242
+ EnsureSpace ensure_space(this);
2243
+ EMIT(0x66);
2244
+ EMIT(0x0F);
2245
+ EMIT(0x3A);
2246
+ EMIT(0x16);
2247
+ emit_sse_operand(src, dst);
2248
+ EMIT(offset);
2249
+ }
2250
+
2251
+
2252
+ void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) {
2253
+ ASSERT(CpuFeatures::IsEnabled(SSE4_1));
2254
+ EnsureSpace ensure_space(this);
2255
+ EMIT(0x66);
2256
+ EMIT(0x0F);
2257
+ EMIT(0x3A);
2258
+ EMIT(0x22);
2259
+ emit_sse_operand(dst, src);
2260
+ EMIT(offset);
2261
+ }
2262
+
2263
+
2264
+ void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2265
+ Register ireg = { reg.code() };
2266
+ emit_operand(ireg, adr);
2267
+ }
2268
+
2269
+
2270
+ void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2271
+ EMIT(0xC0 | dst.code() << 3 | src.code());
2272
+ }
2273
+
2274
+
2275
+ void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2276
+ EMIT(0xC0 | dst.code() << 3 | src.code());
2277
+ }
2278
+
2279
+
2280
+ void Assembler::Print() {
2281
+ Disassembler::Decode(stdout, buffer_, pc_);
2282
+ }
2283
+
2284
+
2285
+ void Assembler::RecordJSReturn() {
2286
+ positions_recorder()->WriteRecordedPositions();
2287
+ EnsureSpace ensure_space(this);
2288
+ RecordRelocInfo(RelocInfo::JS_RETURN);
2289
+ }
2290
+
2291
+
2292
+ void Assembler::RecordDebugBreakSlot() {
2293
+ positions_recorder()->WriteRecordedPositions();
2294
+ EnsureSpace ensure_space(this);
2295
+ RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2296
+ }
2297
+
2298
+
2299
+ void Assembler::RecordComment(const char* msg, bool force) {
2300
+ if (FLAG_code_comments || force) {
2301
+ EnsureSpace ensure_space(this);
2302
+ RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2303
+ }
2304
+ }
2305
+
2306
+
2307
+ void Assembler::GrowBuffer() {
2308
+ ASSERT(overflow());
2309
+ if (!own_buffer_) FATAL("external code buffer is too small");
2310
+
2311
+ // Compute new buffer size.
2312
+ CodeDesc desc; // the new buffer
2313
+ if (buffer_size_ < 4*KB) {
2314
+ desc.buffer_size = 4*KB;
2315
+ } else {
2316
+ desc.buffer_size = 2*buffer_size_;
2317
+ }
2318
+ // Some internal data structures overflow for very large buffers,
2319
+ // they must ensure that kMaximalBufferSize is not too large.
2320
+ if ((desc.buffer_size > kMaximalBufferSize) ||
2321
+ (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
2322
+ V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
2323
+ }
2324
+
2325
+ // Setup new buffer.
2326
+ desc.buffer = NewArray<byte>(desc.buffer_size);
2327
+ desc.instr_size = pc_offset();
2328
+ desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
2329
+
2330
+ // Clear the buffer in debug mode. Use 'int3' instructions to make
2331
+ // sure to get into problems if we ever run uninitialized code.
2332
+ #ifdef DEBUG
2333
+ memset(desc.buffer, 0xCC, desc.buffer_size);
2334
+ #endif
2335
+
2336
+ // Copy the data.
2337
+ int pc_delta = desc.buffer - buffer_;
2338
+ int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2339
+ memmove(desc.buffer, buffer_, desc.instr_size);
2340
+ memmove(rc_delta + reloc_info_writer.pos(),
2341
+ reloc_info_writer.pos(), desc.reloc_size);
2342
+
2343
+ // Switch buffers.
2344
+ if (isolate()->assembler_spare_buffer() == NULL &&
2345
+ buffer_size_ == kMinimalBufferSize) {
2346
+ isolate()->set_assembler_spare_buffer(buffer_);
2347
+ } else {
2348
+ DeleteArray(buffer_);
2349
+ }
2350
+ buffer_ = desc.buffer;
2351
+ buffer_size_ = desc.buffer_size;
2352
+ pc_ += pc_delta;
2353
+ reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2354
+ reloc_info_writer.last_pc() + pc_delta);
2355
+
2356
+ // Relocate runtime entries.
2357
+ for (RelocIterator it(desc); !it.done(); it.next()) {
2358
+ RelocInfo::Mode rmode = it.rinfo()->rmode();
2359
+ if (rmode == RelocInfo::RUNTIME_ENTRY) {
2360
+ int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
2361
+ *p -= pc_delta; // relocate entry
2362
+ } else if (rmode == RelocInfo::INTERNAL_REFERENCE) {
2363
+ int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
2364
+ if (*p != 0) { // 0 means uninitialized.
2365
+ *p += pc_delta;
2366
+ }
2367
+ }
2368
+ }
2369
+
2370
+ ASSERT(!overflow());
2371
+ }
2372
+
2373
+
2374
+ void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
2375
+ ASSERT(is_uint8(op1) && is_uint8(op2)); // wrong opcode
2376
+ ASSERT(is_uint8(imm8));
2377
+ ASSERT((op1 & 0x01) == 0); // should be 8bit operation
2378
+ EMIT(op1);
2379
+ EMIT(op2 | dst.code());
2380
+ EMIT(imm8);
2381
+ }
2382
+
2383
+
2384
+ void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
2385
+ ASSERT((0 <= sel) && (sel <= 7));
2386
+ Register ireg = { sel };
2387
+ if (x.is_int8()) {
2388
+ EMIT(0x83); // using a sign-extended 8-bit immediate.
2389
+ emit_operand(ireg, dst);
2390
+ EMIT(x.x_ & 0xFF);
2391
+ } else if (dst.is_reg(eax)) {
2392
+ EMIT((sel << 3) | 0x05); // short form if the destination is eax.
2393
+ emit(x);
2394
+ } else {
2395
+ EMIT(0x81); // using a literal 32-bit immediate.
2396
+ emit_operand(ireg, dst);
2397
+ emit(x);
2398
+ }
2399
+ }
2400
+
2401
+
2402
+ void Assembler::emit_operand(Register reg, const Operand& adr) {
2403
+ const unsigned length = adr.len_;
2404
+ ASSERT(length > 0);
2405
+
2406
+ // Emit updated ModRM byte containing the given register.
2407
+ pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2408
+
2409
+ // Emit the rest of the encoded operand.
2410
+ for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
2411
+ pc_ += length;
2412
+
2413
+ // Emit relocation information if necessary.
2414
+ if (length >= sizeof(int32_t) && adr.rmode_ != RelocInfo::NONE) {
2415
+ pc_ -= sizeof(int32_t); // pc_ must be *at* disp32
2416
+ RecordRelocInfo(adr.rmode_);
2417
+ pc_ += sizeof(int32_t);
2418
+ }
2419
+ }
2420
+
2421
+
2422
+ void Assembler::emit_farith(int b1, int b2, int i) {
2423
+ ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2424
+ ASSERT(0 <= i && i < 8); // illegal stack offset
2425
+ EMIT(b1);
2426
+ EMIT(b2 + i);
2427
+ }
2428
+
2429
+
2430
+ void Assembler::db(uint8_t data) {
2431
+ EnsureSpace ensure_space(this);
2432
+ EMIT(data);
2433
+ }
2434
+
2435
+
2436
+ void Assembler::dd(uint32_t data) {
2437
+ EnsureSpace ensure_space(this);
2438
+ emit(data);
2439
+ }
2440
+
2441
+
2442
+ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2443
+ ASSERT(rmode != RelocInfo::NONE);
2444
+ // Don't record external references unless the heap will be serialized.
2445
+ if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2446
+ #ifdef DEBUG
2447
+ if (!Serializer::enabled()) {
2448
+ Serializer::TooLateToEnableNow();
2449
+ }
2450
+ #endif
2451
+ if (!Serializer::enabled() && !emit_debug_code()) {
2452
+ return;
2453
+ }
2454
+ }
2455
+ RelocInfo rinfo(pc_, rmode, data);
2456
+ reloc_info_writer.Write(&rinfo);
2457
+ }
2458
+
2459
+
2460
+ #ifdef GENERATED_CODE_COVERAGE
2461
+ static FILE* coverage_log = NULL;
2462
+
2463
+
2464
+ static void InitCoverageLog() {
2465
+ char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
2466
+ if (file_name != NULL) {
2467
+ coverage_log = fopen(file_name, "aw+");
2468
+ }
2469
+ }
2470
+
2471
+
2472
+ void LogGeneratedCodeCoverage(const char* file_line) {
2473
+ const char* return_address = (&file_line)[-1];
2474
+ char* push_insn = const_cast<char*>(return_address - 12);
2475
+ push_insn[0] = 0xeb; // Relative branch insn.
2476
+ push_insn[1] = 13; // Skip over coverage insns.
2477
+ if (coverage_log != NULL) {
2478
+ fprintf(coverage_log, "%s\n", file_line);
2479
+ fflush(coverage_log);
2480
+ }
2481
+ }
2482
+
2483
+ #endif
2484
+
2485
+ } } // namespace v8::internal
2486
+
2487
+ #endif // V8_TARGET_ARCH_IA32