mustang 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Isolate +9 -0
- data/README.md +6 -12
- data/Rakefile +30 -4
- data/TODO.md +9 -0
- data/ext/v8/extconf.rb +56 -0
- data/ext/v8/v8.cpp +37 -0
- data/ext/v8/v8_array.cpp +161 -0
- data/ext/v8/v8_array.h +17 -0
- data/ext/v8/v8_base.cpp +147 -0
- data/ext/v8/v8_base.h +23 -0
- data/ext/v8/v8_cast.cpp +151 -0
- data/ext/v8/v8_cast.h +64 -0
- data/ext/v8/v8_context.cpp +174 -0
- data/ext/v8/v8_context.h +12 -0
- data/ext/v8/v8_date.cpp +61 -0
- data/ext/v8/v8_date.h +16 -0
- data/ext/v8/v8_errors.cpp +147 -0
- data/ext/v8/v8_errors.h +19 -0
- data/ext/v8/v8_external.cpp +66 -0
- data/ext/v8/v8_external.h +16 -0
- data/ext/v8/v8_function.cpp +182 -0
- data/ext/v8/v8_function.h +14 -0
- data/ext/v8/v8_integer.cpp +70 -0
- data/ext/v8/v8_integer.h +16 -0
- data/ext/v8/v8_macros.h +30 -0
- data/ext/v8/v8_main.cpp +53 -0
- data/ext/v8/v8_main.h +13 -0
- data/ext/v8/v8_number.cpp +62 -0
- data/ext/v8/v8_number.h +16 -0
- data/ext/v8/v8_object.cpp +172 -0
- data/ext/v8/v8_object.h +17 -0
- data/ext/v8/v8_ref.cpp +72 -0
- data/ext/v8/v8_ref.h +43 -0
- data/ext/v8/v8_regexp.cpp +148 -0
- data/ext/v8/v8_regexp.h +16 -0
- data/ext/v8/v8_string.cpp +78 -0
- data/ext/v8/v8_string.h +16 -0
- data/ext/v8/v8_value.cpp +370 -0
- data/ext/v8/v8_value.h +19 -0
- data/gemspec.yml +2 -1
- data/lib/core_ext/class.rb +14 -0
- data/lib/core_ext/object.rb +12 -0
- data/lib/core_ext/symbol.rb +23 -0
- data/lib/mustang.rb +44 -0
- data/lib/mustang/context.rb +69 -0
- data/lib/mustang/errors.rb +36 -0
- data/lib/support/delegated.rb +25 -0
- data/lib/v8/array.rb +21 -0
- data/lib/v8/context.rb +13 -0
- data/lib/v8/date.rb +20 -0
- data/lib/v8/error.rb +15 -0
- data/lib/v8/external.rb +16 -0
- data/lib/v8/function.rb +11 -0
- data/lib/v8/integer.rb +16 -0
- data/lib/v8/number.rb +16 -0
- data/lib/v8/object.rb +66 -0
- data/lib/v8/regexp.rb +23 -0
- data/lib/v8/string.rb +27 -0
- data/mustang.gemspec +3 -0
- data/spec/core_ext/class_spec.rb +19 -0
- data/spec/core_ext/object_spec.rb +19 -0
- data/spec/core_ext/symbol_spec.rb +27 -0
- data/spec/fixtures/test1.js +2 -0
- data/spec/fixtures/test2.js +2 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/v8/array_spec.rb +88 -0
- data/spec/v8/cast_spec.rb +151 -0
- data/spec/v8/context_spec.rb +78 -0
- data/spec/v8/data_spec.rb +39 -0
- data/spec/v8/date_spec.rb +45 -0
- data/spec/v8/empty_spec.rb +27 -0
- data/spec/v8/errors_spec.rb +142 -0
- data/spec/v8/external_spec.rb +44 -0
- data/spec/v8/function_spec.rb +170 -0
- data/spec/v8/integer_spec.rb +41 -0
- data/spec/v8/main_spec.rb +18 -0
- data/spec/v8/null_spec.rb +27 -0
- data/spec/v8/number_spec.rb +40 -0
- data/spec/v8/object_spec.rb +79 -0
- data/spec/v8/primitive_spec.rb +9 -0
- data/spec/v8/regexp_spec.rb +65 -0
- data/spec/v8/string_spec.rb +48 -0
- data/spec/v8/undefined_spec.rb +27 -0
- data/spec/v8/value_spec.rb +215 -0
- data/vendor/v8/.gitignore +2 -0
- data/vendor/v8/AUTHORS +3 -1
- data/vendor/v8/ChangeLog +117 -0
- data/vendor/v8/SConstruct +334 -53
- data/vendor/v8/include/v8-debug.h +21 -11
- data/vendor/v8/include/v8-preparser.h +1 -1
- data/vendor/v8/include/v8-profiler.h +122 -43
- data/vendor/v8/include/v8-testing.h +5 -0
- data/vendor/v8/include/v8.h +171 -17
- data/vendor/v8/preparser/SConscript +38 -0
- data/vendor/v8/preparser/preparser-process.cc +77 -114
- data/vendor/v8/samples/shell.cc +232 -46
- data/vendor/v8/src/SConscript +29 -5
- data/vendor/v8/src/accessors.cc +70 -211
- data/vendor/v8/{test/cctest/test-mips.cc → src/allocation-inl.h} +15 -18
- data/vendor/v8/src/allocation.cc +0 -82
- data/vendor/v8/src/allocation.h +9 -42
- data/vendor/v8/src/api.cc +1645 -1156
- data/vendor/v8/src/api.h +76 -12
- data/vendor/v8/src/apiutils.h +0 -7
- data/vendor/v8/src/arguments.h +15 -4
- data/vendor/v8/src/arm/assembler-arm-inl.h +10 -9
- data/vendor/v8/src/arm/assembler-arm.cc +62 -23
- data/vendor/v8/src/arm/assembler-arm.h +76 -11
- data/vendor/v8/src/arm/builtins-arm.cc +39 -33
- data/vendor/v8/src/arm/code-stubs-arm.cc +1182 -402
- data/vendor/v8/src/arm/code-stubs-arm.h +20 -54
- data/vendor/v8/src/arm/codegen-arm.cc +159 -106
- data/vendor/v8/src/arm/codegen-arm.h +6 -6
- data/vendor/v8/src/arm/constants-arm.h +16 -1
- data/vendor/v8/src/arm/cpu-arm.cc +7 -5
- data/vendor/v8/src/arm/debug-arm.cc +6 -4
- data/vendor/v8/src/arm/deoptimizer-arm.cc +51 -14
- data/vendor/v8/src/arm/disasm-arm.cc +47 -15
- data/vendor/v8/src/arm/frames-arm.h +1 -1
- data/vendor/v8/src/arm/full-codegen-arm.cc +724 -408
- data/vendor/v8/src/arm/ic-arm.cc +90 -85
- data/vendor/v8/src/arm/lithium-arm.cc +140 -69
- data/vendor/v8/src/arm/lithium-arm.h +161 -46
- data/vendor/v8/src/arm/lithium-codegen-arm.cc +567 -297
- data/vendor/v8/src/arm/lithium-codegen-arm.h +21 -9
- data/vendor/v8/src/arm/lithium-gap-resolver-arm.cc +2 -0
- data/vendor/v8/src/arm/macro-assembler-arm.cc +457 -96
- data/vendor/v8/src/arm/macro-assembler-arm.h +115 -18
- data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +20 -13
- data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +1 -0
- data/vendor/v8/src/arm/simulator-arm.cc +184 -101
- data/vendor/v8/src/arm/simulator-arm.h +26 -21
- data/vendor/v8/src/arm/stub-cache-arm.cc +450 -467
- data/vendor/v8/src/arm/virtual-frame-arm.cc +14 -12
- data/vendor/v8/src/arm/virtual-frame-arm.h +11 -8
- data/vendor/v8/src/array.js +35 -18
- data/vendor/v8/src/assembler.cc +186 -92
- data/vendor/v8/src/assembler.h +106 -69
- data/vendor/v8/src/ast-inl.h +5 -0
- data/vendor/v8/src/ast.cc +46 -35
- data/vendor/v8/src/ast.h +107 -50
- data/vendor/v8/src/atomicops.h +2 -0
- data/vendor/v8/src/atomicops_internals_mips_gcc.h +169 -0
- data/vendor/v8/src/bootstrapper.cc +649 -399
- data/vendor/v8/src/bootstrapper.h +94 -27
- data/vendor/v8/src/builtins.cc +359 -227
- data/vendor/v8/src/builtins.h +157 -123
- data/vendor/v8/src/checks.cc +2 -2
- data/vendor/v8/src/checks.h +4 -0
- data/vendor/v8/src/code-stubs.cc +27 -17
- data/vendor/v8/src/code-stubs.h +38 -17
- data/vendor/v8/src/codegen-inl.h +5 -1
- data/vendor/v8/src/codegen.cc +27 -17
- data/vendor/v8/src/codegen.h +9 -9
- data/vendor/v8/src/compilation-cache.cc +92 -206
- data/vendor/v8/src/compilation-cache.h +205 -30
- data/vendor/v8/src/compiler.cc +107 -120
- data/vendor/v8/src/compiler.h +17 -2
- data/vendor/v8/src/contexts.cc +22 -15
- data/vendor/v8/src/contexts.h +14 -8
- data/vendor/v8/src/conversions.cc +86 -30
- data/vendor/v8/src/counters.cc +19 -4
- data/vendor/v8/src/counters.h +28 -16
- data/vendor/v8/src/cpu-profiler-inl.h +4 -3
- data/vendor/v8/src/cpu-profiler.cc +123 -72
- data/vendor/v8/src/cpu-profiler.h +33 -19
- data/vendor/v8/src/cpu.h +2 -0
- data/vendor/v8/src/d8-debug.cc +3 -3
- data/vendor/v8/src/d8-debug.h +7 -6
- data/vendor/v8/src/d8-posix.cc +2 -0
- data/vendor/v8/src/d8.cc +22 -12
- data/vendor/v8/src/d8.gyp +3 -0
- data/vendor/v8/src/d8.js +618 -0
- data/vendor/v8/src/data-flow.h +3 -3
- data/vendor/v8/src/dateparser.h +4 -2
- data/vendor/v8/src/debug-agent.cc +10 -9
- data/vendor/v8/src/debug-agent.h +9 -11
- data/vendor/v8/src/debug-debugger.js +121 -0
- data/vendor/v8/src/debug.cc +331 -227
- data/vendor/v8/src/debug.h +248 -219
- data/vendor/v8/src/deoptimizer.cc +173 -62
- data/vendor/v8/src/deoptimizer.h +119 -19
- data/vendor/v8/src/disasm.h +3 -0
- data/vendor/v8/src/disassembler.cc +10 -9
- data/vendor/v8/src/execution.cc +185 -129
- data/vendor/v8/src/execution.h +47 -78
- data/vendor/v8/src/extensions/experimental/break-iterator.cc +250 -0
- data/vendor/v8/src/extensions/experimental/break-iterator.h +89 -0
- data/vendor/v8/src/extensions/experimental/experimental.gyp +2 -0
- data/vendor/v8/src/extensions/experimental/i18n-extension.cc +22 -2
- data/vendor/v8/src/extensions/externalize-string-extension.cc +2 -2
- data/vendor/v8/src/extensions/gc-extension.cc +1 -1
- data/vendor/v8/src/factory.cc +261 -154
- data/vendor/v8/src/factory.h +162 -158
- data/vendor/v8/src/flag-definitions.h +17 -11
- data/vendor/v8/src/frame-element.cc +0 -5
- data/vendor/v8/src/frame-element.h +9 -13
- data/vendor/v8/src/frames-inl.h +7 -0
- data/vendor/v8/src/frames.cc +56 -46
- data/vendor/v8/src/frames.h +36 -25
- data/vendor/v8/src/full-codegen.cc +15 -24
- data/vendor/v8/src/full-codegen.h +13 -41
- data/vendor/v8/src/func-name-inferrer.cc +7 -6
- data/vendor/v8/src/func-name-inferrer.h +1 -1
- data/vendor/v8/src/gdb-jit.cc +1 -0
- data/vendor/v8/src/global-handles.cc +118 -56
- data/vendor/v8/src/global-handles.h +98 -40
- data/vendor/v8/src/globals.h +2 -2
- data/vendor/v8/src/handles-inl.h +106 -9
- data/vendor/v8/src/handles.cc +220 -157
- data/vendor/v8/src/handles.h +38 -59
- data/vendor/v8/src/hashmap.h +3 -3
- data/vendor/v8/src/heap-inl.h +141 -25
- data/vendor/v8/src/heap-profiler.cc +117 -63
- data/vendor/v8/src/heap-profiler.h +38 -21
- data/vendor/v8/src/heap.cc +805 -564
- data/vendor/v8/src/heap.h +640 -594
- data/vendor/v8/src/hydrogen-instructions.cc +216 -73
- data/vendor/v8/src/hydrogen-instructions.h +259 -124
- data/vendor/v8/src/hydrogen.cc +996 -1171
- data/vendor/v8/src/hydrogen.h +163 -144
- data/vendor/v8/src/ia32/assembler-ia32-inl.h +12 -11
- data/vendor/v8/src/ia32/assembler-ia32.cc +85 -39
- data/vendor/v8/src/ia32/assembler-ia32.h +82 -16
- data/vendor/v8/src/ia32/builtins-ia32.cc +64 -58
- data/vendor/v8/src/ia32/code-stubs-ia32.cc +248 -324
- data/vendor/v8/src/ia32/code-stubs-ia32.h +3 -44
- data/vendor/v8/src/ia32/codegen-ia32.cc +217 -165
- data/vendor/v8/src/ia32/codegen-ia32.h +3 -0
- data/vendor/v8/src/ia32/cpu-ia32.cc +6 -5
- data/vendor/v8/src/ia32/debug-ia32.cc +8 -5
- data/vendor/v8/src/ia32/deoptimizer-ia32.cc +124 -14
- data/vendor/v8/src/ia32/disasm-ia32.cc +85 -62
- data/vendor/v8/src/ia32/frames-ia32.h +1 -1
- data/vendor/v8/src/ia32/full-codegen-ia32.cc +348 -435
- data/vendor/v8/src/ia32/ic-ia32.cc +91 -91
- data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +500 -255
- data/vendor/v8/src/ia32/lithium-codegen-ia32.h +13 -4
- data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.cc +6 -0
- data/vendor/v8/src/ia32/lithium-ia32.cc +122 -45
- data/vendor/v8/src/ia32/lithium-ia32.h +128 -41
- data/vendor/v8/src/ia32/macro-assembler-ia32.cc +109 -84
- data/vendor/v8/src/ia32/macro-assembler-ia32.h +18 -9
- data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +26 -15
- data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +1 -0
- data/vendor/v8/src/ia32/register-allocator-ia32.cc +30 -30
- data/vendor/v8/src/ia32/simulator-ia32.h +4 -4
- data/vendor/v8/src/ia32/stub-cache-ia32.cc +383 -400
- data/vendor/v8/src/ia32/virtual-frame-ia32.cc +36 -13
- data/vendor/v8/src/ia32/virtual-frame-ia32.h +11 -5
- data/vendor/v8/src/ic-inl.h +12 -2
- data/vendor/v8/src/ic.cc +304 -221
- data/vendor/v8/src/ic.h +115 -58
- data/vendor/v8/src/interpreter-irregexp.cc +25 -21
- data/vendor/v8/src/interpreter-irregexp.h +2 -1
- data/vendor/v8/src/isolate.cc +883 -0
- data/vendor/v8/src/isolate.h +1304 -0
- data/vendor/v8/src/json.js +10 -10
- data/vendor/v8/src/jsregexp.cc +111 -80
- data/vendor/v8/src/jsregexp.h +6 -7
- data/vendor/v8/src/jump-target-heavy.cc +5 -8
- data/vendor/v8/src/jump-target-heavy.h +0 -6
- data/vendor/v8/src/jump-target-inl.h +1 -1
- data/vendor/v8/src/jump-target-light.cc +3 -3
- data/vendor/v8/src/lithium-allocator-inl.h +2 -0
- data/vendor/v8/src/lithium-allocator.cc +42 -30
- data/vendor/v8/src/lithium-allocator.h +8 -22
- data/vendor/v8/src/lithium.cc +1 -0
- data/vendor/v8/src/liveedit.cc +141 -99
- data/vendor/v8/src/liveedit.h +7 -2
- data/vendor/v8/src/liveobjectlist-inl.h +90 -0
- data/vendor/v8/src/liveobjectlist.cc +2537 -1
- data/vendor/v8/src/liveobjectlist.h +245 -35
- data/vendor/v8/src/log-utils.cc +122 -35
- data/vendor/v8/src/log-utils.h +33 -36
- data/vendor/v8/src/log.cc +299 -241
- data/vendor/v8/src/log.h +177 -110
- data/vendor/v8/src/mark-compact.cc +612 -470
- data/vendor/v8/src/mark-compact.h +153 -80
- data/vendor/v8/src/messages.cc +16 -14
- data/vendor/v8/src/messages.js +30 -7
- data/vendor/v8/src/mips/assembler-mips-inl.h +155 -35
- data/vendor/v8/src/mips/assembler-mips.cc +1093 -219
- data/vendor/v8/src/mips/assembler-mips.h +552 -153
- data/vendor/v8/src/mips/builtins-mips.cc +43 -100
- data/vendor/v8/src/mips/code-stubs-mips.cc +752 -0
- data/vendor/v8/src/mips/code-stubs-mips.h +511 -0
- data/vendor/v8/src/mips/codegen-mips-inl.h +8 -14
- data/vendor/v8/src/mips/codegen-mips.cc +672 -896
- data/vendor/v8/src/mips/codegen-mips.h +271 -69
- data/vendor/v8/src/mips/constants-mips.cc +44 -20
- data/vendor/v8/src/mips/constants-mips.h +238 -40
- data/vendor/v8/src/mips/cpu-mips.cc +20 -3
- data/vendor/v8/src/mips/debug-mips.cc +35 -7
- data/vendor/v8/src/mips/deoptimizer-mips.cc +91 -0
- data/vendor/v8/src/mips/disasm-mips.cc +329 -93
- data/vendor/v8/src/mips/frames-mips.cc +2 -50
- data/vendor/v8/src/mips/frames-mips.h +24 -9
- data/vendor/v8/src/mips/full-codegen-mips.cc +473 -23
- data/vendor/v8/src/mips/ic-mips.cc +81 -45
- data/vendor/v8/src/mips/jump-target-mips.cc +11 -106
- data/vendor/v8/src/mips/lithium-codegen-mips.h +65 -0
- data/vendor/v8/src/mips/lithium-mips.h +304 -0
- data/vendor/v8/src/mips/macro-assembler-mips.cc +2391 -390
- data/vendor/v8/src/mips/macro-assembler-mips.h +718 -121
- data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +478 -0
- data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +250 -0
- data/vendor/v8/src/mips/register-allocator-mips-inl.h +0 -3
- data/vendor/v8/src/mips/register-allocator-mips.h +3 -2
- data/vendor/v8/src/mips/simulator-mips.cc +1009 -221
- data/vendor/v8/src/mips/simulator-mips.h +119 -36
- data/vendor/v8/src/mips/stub-cache-mips.cc +331 -148
- data/vendor/v8/src/mips/{fast-codegen-mips.cc → virtual-frame-mips-inl.h} +11 -30
- data/vendor/v8/src/mips/virtual-frame-mips.cc +137 -149
- data/vendor/v8/src/mips/virtual-frame-mips.h +294 -312
- data/vendor/v8/src/mirror-debugger.js +9 -8
- data/vendor/v8/src/mksnapshot.cc +2 -2
- data/vendor/v8/src/objects-debug.cc +16 -16
- data/vendor/v8/src/objects-inl.h +421 -195
- data/vendor/v8/src/objects-printer.cc +7 -7
- data/vendor/v8/src/objects-visiting.cc +1 -1
- data/vendor/v8/src/objects-visiting.h +33 -12
- data/vendor/v8/src/objects.cc +935 -658
- data/vendor/v8/src/objects.h +234 -139
- data/vendor/v8/src/parser.cc +484 -439
- data/vendor/v8/src/parser.h +35 -14
- data/vendor/v8/src/platform-cygwin.cc +173 -107
- data/vendor/v8/src/platform-freebsd.cc +224 -72
- data/vendor/v8/src/platform-linux.cc +234 -95
- data/vendor/v8/src/platform-macos.cc +215 -82
- data/vendor/v8/src/platform-nullos.cc +9 -3
- data/vendor/v8/src/platform-openbsd.cc +22 -7
- data/vendor/v8/src/platform-posix.cc +30 -5
- data/vendor/v8/src/platform-solaris.cc +120 -38
- data/vendor/v8/src/platform-tls-mac.h +62 -0
- data/vendor/v8/src/platform-tls-win32.h +62 -0
- data/vendor/v8/src/platform-tls.h +50 -0
- data/vendor/v8/src/platform-win32.cc +195 -97
- data/vendor/v8/src/platform.h +72 -15
- data/vendor/v8/src/preparse-data.cc +2 -0
- data/vendor/v8/src/preparser-api.cc +8 -2
- data/vendor/v8/src/preparser.cc +1 -1
- data/vendor/v8/src/prettyprinter.cc +43 -52
- data/vendor/v8/src/prettyprinter.h +1 -1
- data/vendor/v8/src/profile-generator-inl.h +0 -28
- data/vendor/v8/src/profile-generator.cc +942 -685
- data/vendor/v8/src/profile-generator.h +210 -176
- data/vendor/v8/src/property.cc +6 -0
- data/vendor/v8/src/property.h +14 -3
- data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +1 -1
- data/vendor/v8/src/regexp-macro-assembler.cc +28 -19
- data/vendor/v8/src/regexp-macro-assembler.h +11 -6
- data/vendor/v8/src/regexp-stack.cc +18 -10
- data/vendor/v8/src/regexp-stack.h +45 -21
- data/vendor/v8/src/regexp.js +3 -3
- data/vendor/v8/src/register-allocator-inl.h +3 -3
- data/vendor/v8/src/register-allocator.cc +1 -7
- data/vendor/v8/src/register-allocator.h +5 -15
- data/vendor/v8/src/rewriter.cc +2 -1
- data/vendor/v8/src/runtime-profiler.cc +158 -128
- data/vendor/v8/src/runtime-profiler.h +131 -15
- data/vendor/v8/src/runtime.cc +2409 -1692
- data/vendor/v8/src/runtime.h +93 -17
- data/vendor/v8/src/safepoint-table.cc +3 -0
- data/vendor/v8/src/safepoint-table.h +9 -3
- data/vendor/v8/src/scanner-base.cc +21 -28
- data/vendor/v8/src/scanner-base.h +22 -11
- data/vendor/v8/src/scanner.cc +3 -5
- data/vendor/v8/src/scanner.h +4 -2
- data/vendor/v8/src/scopeinfo.cc +11 -16
- data/vendor/v8/src/scopeinfo.h +26 -15
- data/vendor/v8/src/scopes.cc +67 -37
- data/vendor/v8/src/scopes.h +26 -12
- data/vendor/v8/src/serialize.cc +193 -154
- data/vendor/v8/src/serialize.h +41 -36
- data/vendor/v8/src/small-pointer-list.h +163 -0
- data/vendor/v8/src/snapshot-common.cc +1 -1
- data/vendor/v8/src/snapshot.h +3 -1
- data/vendor/v8/src/spaces-inl.h +30 -25
- data/vendor/v8/src/spaces.cc +263 -370
- data/vendor/v8/src/spaces.h +178 -166
- data/vendor/v8/src/string-search.cc +4 -3
- data/vendor/v8/src/string-search.h +21 -20
- data/vendor/v8/src/string-stream.cc +32 -24
- data/vendor/v8/src/string.js +7 -7
- data/vendor/v8/src/stub-cache.cc +324 -248
- data/vendor/v8/src/stub-cache.h +181 -155
- data/vendor/v8/src/token.cc +3 -3
- data/vendor/v8/src/token.h +3 -3
- data/vendor/v8/src/top.cc +218 -390
- data/vendor/v8/src/type-info.cc +98 -32
- data/vendor/v8/src/type-info.h +10 -3
- data/vendor/v8/src/unicode.cc +1 -1
- data/vendor/v8/src/unicode.h +1 -1
- data/vendor/v8/src/utils.h +3 -0
- data/vendor/v8/src/v8-counters.cc +18 -11
- data/vendor/v8/src/v8-counters.h +34 -13
- data/vendor/v8/src/v8.cc +66 -121
- data/vendor/v8/src/v8.h +7 -4
- data/vendor/v8/src/v8globals.h +18 -12
- data/vendor/v8/src/{memory.h → v8memory.h} +0 -0
- data/vendor/v8/src/v8natives.js +59 -18
- data/vendor/v8/src/v8threads.cc +127 -114
- data/vendor/v8/src/v8threads.h +42 -35
- data/vendor/v8/src/v8utils.h +2 -39
- data/vendor/v8/src/variables.h +1 -1
- data/vendor/v8/src/version.cc +26 -5
- data/vendor/v8/src/version.h +4 -0
- data/vendor/v8/src/virtual-frame-heavy-inl.h +2 -4
- data/vendor/v8/src/virtual-frame-light-inl.h +5 -4
- data/vendor/v8/src/vm-state-inl.h +21 -17
- data/vendor/v8/src/vm-state.h +7 -5
- data/vendor/v8/src/win32-headers.h +1 -0
- data/vendor/v8/src/x64/assembler-x64-inl.h +12 -11
- data/vendor/v8/src/x64/assembler-x64.cc +80 -40
- data/vendor/v8/src/x64/assembler-x64.h +67 -17
- data/vendor/v8/src/x64/builtins-x64.cc +34 -33
- data/vendor/v8/src/x64/code-stubs-x64.cc +636 -377
- data/vendor/v8/src/x64/code-stubs-x64.h +14 -48
- data/vendor/v8/src/x64/codegen-x64-inl.h +1 -1
- data/vendor/v8/src/x64/codegen-x64.cc +158 -136
- data/vendor/v8/src/x64/codegen-x64.h +4 -1
- data/vendor/v8/src/x64/cpu-x64.cc +7 -5
- data/vendor/v8/src/x64/debug-x64.cc +8 -6
- data/vendor/v8/src/x64/deoptimizer-x64.cc +195 -20
- data/vendor/v8/src/x64/disasm-x64.cc +42 -23
- data/vendor/v8/src/x64/frames-x64.cc +1 -1
- data/vendor/v8/src/x64/frames-x64.h +2 -2
- data/vendor/v8/src/x64/full-codegen-x64.cc +780 -218
- data/vendor/v8/src/x64/ic-x64.cc +77 -79
- data/vendor/v8/src/x64/jump-target-x64.cc +1 -1
- data/vendor/v8/src/x64/lithium-codegen-x64.cc +698 -181
- data/vendor/v8/src/x64/lithium-codegen-x64.h +31 -6
- data/vendor/v8/src/x64/lithium-x64.cc +136 -54
- data/vendor/v8/src/x64/lithium-x64.h +142 -51
- data/vendor/v8/src/x64/macro-assembler-x64.cc +456 -187
- data/vendor/v8/src/x64/macro-assembler-x64.h +166 -34
- data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +44 -28
- data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +8 -4
- data/vendor/v8/src/x64/register-allocator-x64-inl.h +3 -3
- data/vendor/v8/src/x64/register-allocator-x64.cc +12 -8
- data/vendor/v8/src/x64/simulator-x64.h +5 -5
- data/vendor/v8/src/x64/stub-cache-x64.cc +299 -344
- data/vendor/v8/src/x64/virtual-frame-x64.cc +37 -13
- data/vendor/v8/src/x64/virtual-frame-x64.h +13 -7
- data/vendor/v8/src/zone-inl.h +49 -3
- data/vendor/v8/src/zone.cc +42 -41
- data/vendor/v8/src/zone.h +37 -34
- data/vendor/v8/test/benchmarks/testcfg.py +100 -0
- data/vendor/v8/test/cctest/SConscript +5 -4
- data/vendor/v8/test/cctest/cctest.h +3 -2
- data/vendor/v8/test/cctest/cctest.status +6 -11
- data/vendor/v8/test/cctest/test-accessors.cc +3 -3
- data/vendor/v8/test/cctest/test-alloc.cc +39 -33
- data/vendor/v8/test/cctest/test-api.cc +1092 -205
- data/vendor/v8/test/cctest/test-assembler-arm.cc +39 -25
- data/vendor/v8/test/cctest/test-assembler-ia32.cc +36 -37
- data/vendor/v8/test/cctest/test-assembler-mips.cc +1098 -40
- data/vendor/v8/test/cctest/test-assembler-x64.cc +32 -25
- data/vendor/v8/test/cctest/test-ast.cc +1 -0
- data/vendor/v8/test/cctest/test-circular-queue.cc +8 -5
- data/vendor/v8/test/cctest/test-compiler.cc +24 -24
- data/vendor/v8/test/cctest/test-cpu-profiler.cc +140 -5
- data/vendor/v8/test/cctest/test-dataflow.cc +1 -0
- data/vendor/v8/test/cctest/test-debug.cc +136 -77
- data/vendor/v8/test/cctest/test-decls.cc +1 -1
- data/vendor/v8/test/cctest/test-deoptimization.cc +25 -24
- data/vendor/v8/test/cctest/test-disasm-arm.cc +9 -4
- data/vendor/v8/test/cctest/test-disasm-ia32.cc +10 -8
- data/vendor/v8/test/cctest/test-func-name-inference.cc +10 -4
- data/vendor/v8/test/cctest/test-heap-profiler.cc +226 -164
- data/vendor/v8/test/cctest/test-heap.cc +240 -217
- data/vendor/v8/test/cctest/test-liveedit.cc +1 -0
- data/vendor/v8/test/cctest/test-log-stack-tracer.cc +18 -20
- data/vendor/v8/test/cctest/test-log.cc +114 -108
- data/vendor/v8/test/cctest/test-macro-assembler-x64.cc +247 -177
- data/vendor/v8/test/cctest/test-mark-compact.cc +129 -90
- data/vendor/v8/test/cctest/test-parsing.cc +15 -14
- data/vendor/v8/test/cctest/test-platform-linux.cc +1 -0
- data/vendor/v8/test/cctest/test-platform-tls.cc +66 -0
- data/vendor/v8/test/cctest/test-platform-win32.cc +1 -0
- data/vendor/v8/test/cctest/test-profile-generator.cc +1 -1
- data/vendor/v8/test/cctest/test-regexp.cc +53 -41
- data/vendor/v8/test/cctest/test-reloc-info.cc +18 -11
- data/vendor/v8/test/cctest/test-serialize.cc +44 -43
- data/vendor/v8/test/cctest/test-sockets.cc +8 -3
- data/vendor/v8/test/cctest/test-spaces.cc +47 -29
- data/vendor/v8/test/cctest/test-strings.cc +20 -20
- data/vendor/v8/test/cctest/test-thread-termination.cc +8 -3
- data/vendor/v8/test/cctest/test-threads.cc +5 -3
- data/vendor/v8/test/cctest/test-utils.cc +5 -4
- data/vendor/v8/test/cctest/testcfg.py +7 -3
- data/vendor/v8/test/es5conform/es5conform.status +2 -77
- data/vendor/v8/test/es5conform/testcfg.py +1 -1
- data/vendor/v8/test/message/testcfg.py +1 -1
- data/vendor/v8/test/mjsunit/accessors-on-global-object.js +3 -3
- data/vendor/v8/test/mjsunit/array-concat.js +43 -1
- data/vendor/v8/test/mjsunit/array-join.js +25 -0
- data/vendor/v8/test/mjsunit/bitops-info.js +7 -1
- data/vendor/v8/test/mjsunit/compiler/array-length.js +2 -2
- data/vendor/v8/test/mjsunit/compiler/global-accessors.js +47 -0
- data/vendor/v8/test/mjsunit/compiler/pic.js +1 -1
- data/vendor/v8/test/mjsunit/compiler/regress-loadfield.js +65 -0
- data/vendor/v8/test/mjsunit/math-sqrt.js +5 -1
- data/vendor/v8/test/mjsunit/mjsunit.js +59 -8
- data/vendor/v8/test/mjsunit/mjsunit.status +0 -12
- data/vendor/v8/test/mjsunit/mul-exhaustive.js +129 -11
- data/vendor/v8/test/mjsunit/negate-zero.js +1 -1
- data/vendor/v8/test/mjsunit/object-freeze.js +5 -13
- data/vendor/v8/test/mjsunit/object-prevent-extensions.js +9 -50
- data/vendor/v8/test/mjsunit/object-seal.js +4 -13
- data/vendor/v8/test/mjsunit/override-eval-with-non-function.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-1145.js +54 -0
- data/vendor/v8/test/mjsunit/regress/regress-1172-bis.js +37 -0
- data/vendor/v8/test/mjsunit/regress/regress-1181.js +54 -0
- data/vendor/v8/test/mjsunit/regress/regress-1207.js +35 -0
- data/vendor/v8/test/mjsunit/regress/regress-1209.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-1210.js +48 -0
- data/vendor/v8/test/mjsunit/regress/regress-1213.js +43 -0
- data/vendor/v8/test/mjsunit/regress/regress-1218.js +29 -0
- data/vendor/v8/test/mjsunit/regress/regress-1229.js +79 -0
- data/vendor/v8/test/mjsunit/regress/regress-1233.js +47 -0
- data/vendor/v8/test/mjsunit/regress/regress-1236.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-1237.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-1240.js +39 -0
- data/vendor/v8/test/mjsunit/regress/regress-1257.js +58 -0
- data/vendor/v8/test/mjsunit/regress/regress-1278.js +69 -0
- data/vendor/v8/test/mjsunit/regress/regress-create-exception.js +1 -0
- data/vendor/v8/test/mjsunit/regress/regress-lazy-deopt-reloc.js +52 -0
- data/vendor/v8/test/mjsunit/sin-cos.js +15 -10
- data/vendor/v8/test/mjsunit/smi-negative-zero.js +2 -2
- data/vendor/v8/test/mjsunit/str-to-num.js +1 -1
- data/vendor/v8/test/mjsunit/strict-mode.js +435 -0
- data/vendor/v8/test/mjsunit/testcfg.py +23 -6
- data/vendor/v8/test/mozilla/mozilla.status +0 -2
- data/vendor/v8/test/mozilla/testcfg.py +1 -1
- data/vendor/v8/test/preparser/empty.js +28 -0
- data/vendor/v8/test/preparser/functions-only.js +38 -0
- data/vendor/v8/test/preparser/non-alphanum.js +34 -0
- data/vendor/v8/test/preparser/symbols-only.js +49 -0
- data/vendor/v8/test/preparser/testcfg.py +90 -0
- data/vendor/v8/test/sputnik/testcfg.py +1 -1
- data/vendor/v8/test/test262/README +16 -0
- data/vendor/v8/test/test262/harness-adapt.js +80 -0
- data/vendor/v8/test/test262/test262.status +1506 -0
- data/vendor/v8/test/test262/testcfg.py +123 -0
- data/vendor/v8/tools/freebsd-tick-processor +10 -0
- data/vendor/v8/tools/gyp/v8.gyp +8 -33
- data/vendor/v8/tools/linux-tick-processor +5 -3
- data/vendor/v8/tools/test.py +37 -14
- data/vendor/v8/tools/tickprocessor.js +22 -8
- data/vendor/v8/tools/visual_studio/v8_base.vcproj +13 -1
- data/vendor/v8/tools/visual_studio/v8_base_arm.vcproj +5 -1
- data/vendor/v8/tools/visual_studio/v8_base_x64.vcproj +5 -1
- data/vendor/v8/tools/visual_studio/x64.vsprops +1 -0
- metadata +1495 -1341
- data/ext/extconf.rb +0 -22
- data/ext/mustang.cpp +0 -58
- data/vendor/v8/src/top.h +0 -608
data/vendor/v8/src/x64/ic-x64.cc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
// Copyright
|
1
|
+
// Copyright 2011 the V8 project authors. All rights reserved.
|
2
2
|
// Redistribution and use in source and binary forms, with or without
|
3
3
|
// modification, are permitted provided that the following conditions are
|
4
4
|
// met:
|
@@ -554,7 +554,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
554
554
|
// -- rsp[0] : return address
|
555
555
|
// -----------------------------------
|
556
556
|
Label slow, check_string, index_smi, index_string, property_array_property;
|
557
|
-
Label
|
557
|
+
Label probe_dictionary, check_number_dictionary;
|
558
558
|
|
559
559
|
// Check that the key is a smi.
|
560
560
|
__ JumpIfNotSmi(rax, &check_string);
|
@@ -569,7 +569,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
569
569
|
// now in rcx.
|
570
570
|
__ testb(FieldOperand(rcx, Map::kBitField2Offset),
|
571
571
|
Immediate(1 << Map::kHasFastElements));
|
572
|
-
__ j(zero, &
|
572
|
+
__ j(zero, &check_number_dictionary);
|
573
573
|
|
574
574
|
GenerateFastArrayLoad(masm,
|
575
575
|
rdx,
|
@@ -579,21 +579,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
579
579
|
rax,
|
580
580
|
NULL,
|
581
581
|
&slow);
|
582
|
-
|
582
|
+
Counters* counters = masm->isolate()->counters();
|
583
|
+
__ IncrementCounter(counters->keyed_load_generic_smi(), 1);
|
583
584
|
__ ret(0);
|
584
585
|
|
585
|
-
__ bind(&check_pixel_array);
|
586
|
-
GenerateFastPixelArrayLoad(masm,
|
587
|
-
rdx,
|
588
|
-
rax,
|
589
|
-
rcx,
|
590
|
-
rbx,
|
591
|
-
rax,
|
592
|
-
&check_number_dictionary,
|
593
|
-
NULL,
|
594
|
-
&slow);
|
595
|
-
|
596
586
|
__ bind(&check_number_dictionary);
|
587
|
+
__ SmiToInteger32(rbx, rax);
|
588
|
+
__ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
|
589
|
+
|
597
590
|
// Check whether the elements is a number dictionary.
|
598
591
|
// rdx: receiver
|
599
592
|
// rax: key
|
@@ -609,7 +602,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
609
602
|
// Slow case: Jump to runtime.
|
610
603
|
// rdx: receiver
|
611
604
|
// rax: key
|
612
|
-
__ IncrementCounter(
|
605
|
+
__ IncrementCounter(counters->keyed_load_generic_slow(), 1);
|
613
606
|
GenerateRuntimeGetProperty(masm);
|
614
607
|
|
615
608
|
__ bind(&check_string);
|
@@ -638,10 +631,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
638
631
|
// Load the key (consisting of map and symbol) from the cache and
|
639
632
|
// check for match.
|
640
633
|
ExternalReference cache_keys
|
641
|
-
= ExternalReference::keyed_lookup_cache_keys();
|
634
|
+
= ExternalReference::keyed_lookup_cache_keys(masm->isolate());
|
642
635
|
__ movq(rdi, rcx);
|
643
636
|
__ shl(rdi, Immediate(kPointerSizeLog2 + 1));
|
644
|
-
__
|
637
|
+
__ LoadAddress(kScratchRegister, cache_keys);
|
645
638
|
__ cmpq(rbx, Operand(kScratchRegister, rdi, times_1, 0));
|
646
639
|
__ j(not_equal, &slow);
|
647
640
|
__ cmpq(rax, Operand(kScratchRegister, rdi, times_1, kPointerSize));
|
@@ -649,8 +642,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
649
642
|
|
650
643
|
// Get field offset, which is a 32-bit integer.
|
651
644
|
ExternalReference cache_field_offsets
|
652
|
-
= ExternalReference::keyed_lookup_cache_field_offsets();
|
653
|
-
__
|
645
|
+
= ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate());
|
646
|
+
__ LoadAddress(kScratchRegister, cache_field_offsets);
|
654
647
|
__ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0));
|
655
648
|
__ movzxbq(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset));
|
656
649
|
__ subq(rdi, rcx);
|
@@ -660,7 +653,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
660
653
|
__ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset));
|
661
654
|
__ addq(rcx, rdi);
|
662
655
|
__ movq(rax, FieldOperand(rdx, rcx, times_pointer_size, 0));
|
663
|
-
__ IncrementCounter(
|
656
|
+
__ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
|
664
657
|
__ ret(0);
|
665
658
|
|
666
659
|
// Load property array property.
|
@@ -668,7 +661,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
668
661
|
__ movq(rax, FieldOperand(rdx, JSObject::kPropertiesOffset));
|
669
662
|
__ movq(rax, FieldOperand(rax, rdi, times_pointer_size,
|
670
663
|
FixedArray::kHeaderSize));
|
671
|
-
__ IncrementCounter(
|
664
|
+
__ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
|
672
665
|
__ ret(0);
|
673
666
|
|
674
667
|
// Do a quick inline probe of the receiver's dictionary, if it
|
@@ -683,7 +676,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
683
676
|
GenerateGlobalInstanceTypeCheck(masm, rcx, &slow);
|
684
677
|
|
685
678
|
GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax);
|
686
|
-
__ IncrementCounter(
|
679
|
+
__ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
|
687
680
|
__ ret(0);
|
688
681
|
|
689
682
|
__ bind(&index_string);
|
@@ -758,22 +751,26 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
|
|
758
751
|
__ push(rcx); // return address
|
759
752
|
|
760
753
|
// Perform tail call to the entry.
|
761
|
-
__ TailCallExternalReference(
|
762
|
-
|
754
|
+
__ TailCallExternalReference(
|
755
|
+
ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor),
|
756
|
+
masm->isolate()),
|
757
|
+
2,
|
758
|
+
1);
|
763
759
|
|
764
760
|
__ bind(&slow);
|
765
761
|
GenerateMiss(masm);
|
766
762
|
}
|
767
763
|
|
768
764
|
|
769
|
-
void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm
|
765
|
+
void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
766
|
+
StrictModeFlag strict_mode) {
|
770
767
|
// ----------- S t a t e -------------
|
771
768
|
// -- rax : value
|
772
769
|
// -- rcx : key
|
773
770
|
// -- rdx : receiver
|
774
771
|
// -- rsp[0] : return address
|
775
772
|
// -----------------------------------
|
776
|
-
Label slow, slow_with_tagged_index, fast, array, extra
|
773
|
+
Label slow, slow_with_tagged_index, fast, array, extra;
|
777
774
|
|
778
775
|
// Check that the object isn't a smi.
|
779
776
|
__ JumpIfSmi(rdx, &slow_with_tagged_index);
|
@@ -802,7 +799,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
|
802
799
|
// Check that the object is in fast mode and writable.
|
803
800
|
__ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
|
804
801
|
Heap::kFixedArrayMapRootIndex);
|
805
|
-
__ j(not_equal, &
|
802
|
+
__ j(not_equal, &slow);
|
806
803
|
__ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
|
807
804
|
// rax: value
|
808
805
|
// rbx: FixedArray
|
@@ -813,28 +810,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
|
813
810
|
__ bind(&slow);
|
814
811
|
__ Integer32ToSmi(rcx, rcx);
|
815
812
|
__ bind(&slow_with_tagged_index);
|
816
|
-
GenerateRuntimeSetProperty(masm);
|
813
|
+
GenerateRuntimeSetProperty(masm, strict_mode);
|
817
814
|
// Never returns to here.
|
818
815
|
|
819
|
-
// Check whether the elements is a pixel array.
|
820
|
-
// rax: value
|
821
|
-
// rdx: receiver
|
822
|
-
// rbx: receiver's elements array
|
823
|
-
// rcx: index, zero-extended.
|
824
|
-
__ bind(&check_pixel_array);
|
825
|
-
GenerateFastPixelArrayStore(masm,
|
826
|
-
rdx,
|
827
|
-
rcx,
|
828
|
-
rax,
|
829
|
-
rbx,
|
830
|
-
rdi,
|
831
|
-
false,
|
832
|
-
true,
|
833
|
-
NULL,
|
834
|
-
&slow,
|
835
|
-
&slow,
|
836
|
-
&slow);
|
837
|
-
|
838
816
|
// Extra capacity case: Check if there is extra capacity to
|
839
817
|
// perform the store and update the length. Used for adding one
|
840
818
|
// element to the array by writing to array[array.length].
|
@@ -906,7 +884,8 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
|
|
906
884
|
Code::kNoExtraICState,
|
907
885
|
NORMAL,
|
908
886
|
argc);
|
909
|
-
|
887
|
+
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
|
888
|
+
rax);
|
910
889
|
|
911
890
|
// If the stub cache probing failed, the receiver might be a value.
|
912
891
|
// For value objects, we use the map of the prototype objects for
|
@@ -942,7 +921,8 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
|
|
942
921
|
|
943
922
|
// Probe the stub cache for the value object.
|
944
923
|
__ bind(&probe);
|
945
|
-
|
924
|
+
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
|
925
|
+
no_reg);
|
946
926
|
|
947
927
|
__ bind(&miss);
|
948
928
|
}
|
@@ -1011,10 +991,11 @@ static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
|
|
1011
991
|
// rsp[(argc + 1) * 8] : argument 0 = receiver
|
1012
992
|
// -----------------------------------
|
1013
993
|
|
994
|
+
Counters* counters = masm->isolate()->counters();
|
1014
995
|
if (id == IC::kCallIC_Miss) {
|
1015
|
-
__ IncrementCounter(
|
996
|
+
__ IncrementCounter(counters->call_miss(), 1);
|
1016
997
|
} else {
|
1017
|
-
__ IncrementCounter(
|
998
|
+
__ IncrementCounter(counters->keyed_call_miss(), 1);
|
1018
999
|
}
|
1019
1000
|
|
1020
1001
|
// Get the receiver of the function from the stack; 1 ~ return address.
|
@@ -1030,7 +1011,7 @@ static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
|
|
1030
1011
|
// Call the entry.
|
1031
1012
|
CEntryStub stub(1);
|
1032
1013
|
__ movq(rax, Immediate(2));
|
1033
|
-
__
|
1014
|
+
__ LoadAddress(rbx, ExternalReference(IC_Utility(id), masm->isolate()));
|
1034
1015
|
__ CallStub(&stub);
|
1035
1016
|
|
1036
1017
|
// Move result to rdi and exit the internal frame.
|
@@ -1140,7 +1121,8 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
|
|
1140
1121
|
|
1141
1122
|
GenerateFastArrayLoad(
|
1142
1123
|
masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load);
|
1143
|
-
|
1124
|
+
Counters* counters = masm->isolate()->counters();
|
1125
|
+
__ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1);
|
1144
1126
|
|
1145
1127
|
__ bind(&do_call);
|
1146
1128
|
// receiver in rdx is not used after this point.
|
@@ -1158,13 +1140,13 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
|
|
1158
1140
|
__ SmiToInteger32(rbx, rcx);
|
1159
1141
|
// ebx: untagged index
|
1160
1142
|
GenerateNumberDictionaryLoad(masm, &slow_load, rax, rcx, rbx, r9, rdi, rdi);
|
1161
|
-
__ IncrementCounter(
|
1143
|
+
__ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
|
1162
1144
|
__ jmp(&do_call);
|
1163
1145
|
|
1164
1146
|
__ bind(&slow_load);
|
1165
1147
|
// This branch is taken when calling KeyedCallIC_Miss is neither required
|
1166
1148
|
// nor beneficial.
|
1167
|
-
__ IncrementCounter(
|
1149
|
+
__ IncrementCounter(counters->keyed_call_generic_slow_load(), 1);
|
1168
1150
|
__ EnterInternalFrame();
|
1169
1151
|
__ push(rcx); // save the key
|
1170
1152
|
__ push(rdx); // pass the receiver
|
@@ -1191,11 +1173,11 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
|
|
1191
1173
|
__ j(not_equal, &lookup_monomorphic_cache);
|
1192
1174
|
|
1193
1175
|
GenerateDictionaryLoad(masm, &slow_load, rbx, rcx, rax, rdi, rdi);
|
1194
|
-
__ IncrementCounter(
|
1176
|
+
__ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1);
|
1195
1177
|
__ jmp(&do_call);
|
1196
1178
|
|
1197
1179
|
__ bind(&lookup_monomorphic_cache);
|
1198
|
-
__ IncrementCounter(
|
1180
|
+
__ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1);
|
1199
1181
|
GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC);
|
1200
1182
|
// Fall through on miss.
|
1201
1183
|
|
@@ -1206,7 +1188,7 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
|
|
1206
1188
|
// - the value loaded is not a function,
|
1207
1189
|
// - there is hope that the runtime will create a monomorphic call stub
|
1208
1190
|
// that will get fetched next time.
|
1209
|
-
__ IncrementCounter(
|
1191
|
+
__ IncrementCounter(counters->keyed_call_generic_slow(), 1);
|
1210
1192
|
GenerateMiss(masm, argc);
|
1211
1193
|
|
1212
1194
|
__ bind(&index_string);
|
@@ -1264,7 +1246,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
|
|
1264
1246
|
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
|
1265
1247
|
NOT_IN_LOOP,
|
1266
1248
|
MONOMORPHIC);
|
1267
|
-
|
1249
|
+
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rax, rcx, rbx,
|
1250
|
+
rdx);
|
1268
1251
|
|
1269
1252
|
// Cache miss: Jump to runtime.
|
1270
1253
|
StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
|
@@ -1299,7 +1282,8 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
|
|
1299
1282
|
// -- rsp[0] : return address
|
1300
1283
|
// -----------------------------------
|
1301
1284
|
|
1302
|
-
|
1285
|
+
Counters* counters = masm->isolate()->counters();
|
1286
|
+
__ IncrementCounter(counters->load_miss(), 1);
|
1303
1287
|
|
1304
1288
|
__ pop(rbx);
|
1305
1289
|
__ push(rax); // receiver
|
@@ -1307,7 +1291,8 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
|
|
1307
1291
|
__ push(rbx); // return address
|
1308
1292
|
|
1309
1293
|
// Perform tail call to the entry.
|
1310
|
-
ExternalReference ref =
|
1294
|
+
ExternalReference ref =
|
1295
|
+
ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
|
1311
1296
|
__ TailCallExternalReference(ref, 2, 1);
|
1312
1297
|
}
|
1313
1298
|
|
@@ -1382,7 +1367,7 @@ bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
|
|
1382
1367
|
// (-1) or we should be clearing the inlined version.
|
1383
1368
|
ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt - 1 ||
|
1384
1369
|
*reinterpret_cast<int*>(offset_address) == -1 ||
|
1385
|
-
(offset == 0 && map ==
|
1370
|
+
(offset == 0 && map == HEAP->null_value()));
|
1386
1371
|
*reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
|
1387
1372
|
|
1388
1373
|
// Patch the offset in the write-barrier code. The offset is the
|
@@ -1392,7 +1377,7 @@ bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
|
|
1392
1377
|
// (-1) or we should be clearing the inlined version.
|
1393
1378
|
ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt ||
|
1394
1379
|
*reinterpret_cast<int*>(offset_address) == -1 ||
|
1395
|
-
(offset == 0 && map ==
|
1380
|
+
(offset == 0 && map == HEAP->null_value()));
|
1396
1381
|
*reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
|
1397
1382
|
|
1398
1383
|
return true;
|
@@ -1443,7 +1428,8 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
|
|
1443
1428
|
// -- rsp[0] : return address
|
1444
1429
|
// -----------------------------------
|
1445
1430
|
|
1446
|
-
|
1431
|
+
Counters* counters = masm->isolate()->counters();
|
1432
|
+
__ IncrementCounter(counters->keyed_load_miss(), 1);
|
1447
1433
|
|
1448
1434
|
__ pop(rbx);
|
1449
1435
|
__ push(rdx); // receiver
|
@@ -1451,7 +1437,8 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
|
|
1451
1437
|
__ push(rbx); // return address
|
1452
1438
|
|
1453
1439
|
// Perform tail call to the entry.
|
1454
|
-
ExternalReference ref
|
1440
|
+
ExternalReference ref
|
1441
|
+
= ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
|
1455
1442
|
__ TailCallExternalReference(ref, 2, 1);
|
1456
1443
|
}
|
1457
1444
|
|
@@ -1474,7 +1461,7 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
|
|
1474
1461
|
|
1475
1462
|
|
1476
1463
|
void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
|
1477
|
-
|
1464
|
+
StrictModeFlag strict_mode) {
|
1478
1465
|
// ----------- S t a t e -------------
|
1479
1466
|
// -- rax : value
|
1480
1467
|
// -- rcx : name
|
@@ -1486,8 +1473,9 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
|
|
1486
1473
|
Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
|
1487
1474
|
NOT_IN_LOOP,
|
1488
1475
|
MONOMORPHIC,
|
1489
|
-
|
1490
|
-
|
1476
|
+
strict_mode);
|
1477
|
+
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
|
1478
|
+
no_reg);
|
1491
1479
|
|
1492
1480
|
// Cache miss: Jump to runtime.
|
1493
1481
|
GenerateMiss(masm);
|
@@ -1509,7 +1497,8 @@ void StoreIC::GenerateMiss(MacroAssembler* masm) {
|
|
1509
1497
|
__ push(rbx); // return address
|
1510
1498
|
|
1511
1499
|
// Perform tail call to the entry.
|
1512
|
-
ExternalReference ref =
|
1500
|
+
ExternalReference ref =
|
1501
|
+
ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate());
|
1513
1502
|
__ TailCallExternalReference(ref, 3, 1);
|
1514
1503
|
}
|
1515
1504
|
|
@@ -1562,7 +1551,8 @@ void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
|
|
1562
1551
|
__ push(value);
|
1563
1552
|
__ push(scratch); // return address
|
1564
1553
|
|
1565
|
-
ExternalReference ref =
|
1554
|
+
ExternalReference ref =
|
1555
|
+
ExternalReference(IC_Utility(kStoreIC_ArrayLength), masm->isolate());
|
1566
1556
|
__ TailCallExternalReference(ref, 2, 1);
|
1567
1557
|
|
1568
1558
|
__ bind(&miss);
|
@@ -1584,16 +1574,18 @@ void StoreIC::GenerateNormal(MacroAssembler* masm) {
|
|
1584
1574
|
GenerateStringDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss);
|
1585
1575
|
|
1586
1576
|
GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9);
|
1587
|
-
|
1577
|
+
Counters* counters = masm->isolate()->counters();
|
1578
|
+
__ IncrementCounter(counters->store_normal_hit(), 1);
|
1588
1579
|
__ ret(0);
|
1589
1580
|
|
1590
1581
|
__ bind(&miss);
|
1591
|
-
__ IncrementCounter(
|
1582
|
+
__ IncrementCounter(counters->store_normal_miss(), 1);
|
1592
1583
|
GenerateMiss(masm);
|
1593
1584
|
}
|
1594
1585
|
|
1595
1586
|
|
1596
|
-
void StoreIC::GenerateGlobalProxy(MacroAssembler* masm
|
1587
|
+
void StoreIC::GenerateGlobalProxy(MacroAssembler* masm,
|
1588
|
+
StrictModeFlag strict_mode) {
|
1597
1589
|
// ----------- S t a t e -------------
|
1598
1590
|
// -- rax : value
|
1599
1591
|
// -- rcx : name
|
@@ -1604,14 +1596,17 @@ void StoreIC::GenerateGlobalProxy(MacroAssembler* masm) {
|
|
1604
1596
|
__ push(rdx);
|
1605
1597
|
__ push(rcx);
|
1606
1598
|
__ push(rax);
|
1607
|
-
__
|
1599
|
+
__ Push(Smi::FromInt(NONE)); // PropertyAttributes
|
1600
|
+
__ Push(Smi::FromInt(strict_mode));
|
1601
|
+
__ push(rbx); // return address
|
1608
1602
|
|
1609
1603
|
// Do tail-call to runtime routine.
|
1610
|
-
__ TailCallRuntime(Runtime::kSetProperty,
|
1604
|
+
__ TailCallRuntime(Runtime::kSetProperty, 5, 1);
|
1611
1605
|
}
|
1612
1606
|
|
1613
1607
|
|
1614
|
-
void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm
|
1608
|
+
void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
|
1609
|
+
StrictModeFlag strict_mode) {
|
1615
1610
|
// ----------- S t a t e -------------
|
1616
1611
|
// -- rax : value
|
1617
1612
|
// -- rcx : key
|
@@ -1623,10 +1618,12 @@ void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
|
|
1623
1618
|
__ push(rdx); // receiver
|
1624
1619
|
__ push(rcx); // key
|
1625
1620
|
__ push(rax); // value
|
1621
|
+
__ Push(Smi::FromInt(NONE)); // PropertyAttributes
|
1622
|
+
__ Push(Smi::FromInt(strict_mode)); // Strict mode.
|
1626
1623
|
__ push(rbx); // return address
|
1627
1624
|
|
1628
1625
|
// Do tail-call to runtime routine.
|
1629
|
-
__ TailCallRuntime(Runtime::kSetProperty,
|
1626
|
+
__ TailCallRuntime(Runtime::kSetProperty, 5, 1);
|
1630
1627
|
}
|
1631
1628
|
|
1632
1629
|
|
@@ -1645,7 +1642,8 @@ void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
|
|
1645
1642
|
__ push(rbx); // return address
|
1646
1643
|
|
1647
1644
|
// Do tail-call to runtime routine.
|
1648
|
-
ExternalReference ref =
|
1645
|
+
ExternalReference ref =
|
1646
|
+
ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
|
1649
1647
|
__ TailCallExternalReference(ref, 3, 1);
|
1650
1648
|
}
|
1651
1649
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// Copyright
|
1
|
+
// Copyright 2010 the V8 project authors. All rights reserved.
|
2
2
|
// Redistribution and use in source and binary forms, with or without
|
3
3
|
// modification, are permitted provided that the following conditions are
|
4
4
|
// met:
|
@@ -39,32 +39,39 @@ namespace internal {
|
|
39
39
|
|
40
40
|
// When invoking builtins, we need to record the safepoint in the middle of
|
41
41
|
// the invoke instruction sequence generated by the macro assembler.
|
42
|
-
class SafepointGenerator : public
|
42
|
+
class SafepointGenerator : public CallWrapper {
|
43
43
|
public:
|
44
44
|
SafepointGenerator(LCodeGen* codegen,
|
45
45
|
LPointerMap* pointers,
|
46
|
-
int deoptimization_index
|
47
|
-
bool ensure_reloc_space = false)
|
46
|
+
int deoptimization_index)
|
48
47
|
: codegen_(codegen),
|
49
48
|
pointers_(pointers),
|
50
|
-
deoptimization_index_(deoptimization_index)
|
51
|
-
ensure_reloc_space_(ensure_reloc_space) { }
|
49
|
+
deoptimization_index_(deoptimization_index) { }
|
52
50
|
virtual ~SafepointGenerator() { }
|
53
51
|
|
54
|
-
virtual void
|
55
|
-
|
56
|
-
//
|
57
|
-
|
58
|
-
|
52
|
+
virtual void BeforeCall(int call_size) {
|
53
|
+
ASSERT(call_size >= 0);
|
54
|
+
// Ensure that we have enough space after the previous safepoint position
|
55
|
+
// for the jump generated there.
|
56
|
+
int call_end = codegen_->masm()->pc_offset() + call_size;
|
57
|
+
int prev_jump_end = codegen_->LastSafepointEnd() + kMinSafepointSize;
|
58
|
+
if (call_end < prev_jump_end) {
|
59
|
+
int padding_size = prev_jump_end - call_end;
|
60
|
+
STATIC_ASSERT(kMinSafepointSize <= 9); // One multibyte nop is enough.
|
61
|
+
codegen_->masm()->nop(padding_size);
|
59
62
|
}
|
63
|
+
}
|
64
|
+
|
65
|
+
virtual void AfterCall() {
|
60
66
|
codegen_->RecordSafepoint(pointers_, deoptimization_index_);
|
61
67
|
}
|
62
68
|
|
63
69
|
private:
|
70
|
+
static const int kMinSafepointSize =
|
71
|
+
MacroAssembler::kShortCallInstructionLength;
|
64
72
|
LCodeGen* codegen_;
|
65
73
|
LPointerMap* pointers_;
|
66
74
|
int deoptimization_index_;
|
67
|
-
bool ensure_reloc_space_;
|
68
75
|
};
|
69
76
|
|
70
77
|
|
@@ -77,6 +84,7 @@ bool LCodeGen::GenerateCode() {
|
|
77
84
|
return GeneratePrologue() &&
|
78
85
|
GenerateBody() &&
|
79
86
|
GenerateDeferredCode() &&
|
87
|
+
GenerateJumpTable() &&
|
80
88
|
GenerateSafepointTable();
|
81
89
|
}
|
82
90
|
|
@@ -86,13 +94,14 @@ void LCodeGen::FinishCode(Handle<Code> code) {
|
|
86
94
|
code->set_stack_slots(StackSlotCount());
|
87
95
|
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
|
88
96
|
PopulateDeoptimizationData(code);
|
97
|
+
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
|
89
98
|
}
|
90
99
|
|
91
100
|
|
92
101
|
void LCodeGen::Abort(const char* format, ...) {
|
93
102
|
if (FLAG_trace_bailout) {
|
94
|
-
SmartPointer<char>
|
95
|
-
PrintF("Aborting LCodeGen in @\"%s\": ", *
|
103
|
+
SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString());
|
104
|
+
PrintF("Aborting LCodeGen in @\"%s\": ", *name);
|
96
105
|
va_list arguments;
|
97
106
|
va_start(arguments, format);
|
98
107
|
OS::VPrint(format, arguments);
|
@@ -240,6 +249,15 @@ LInstruction* LCodeGen::GetNextInstruction() {
|
|
240
249
|
}
|
241
250
|
|
242
251
|
|
252
|
+
bool LCodeGen::GenerateJumpTable() {
|
253
|
+
for (int i = 0; i < jump_table_.length(); i++) {
|
254
|
+
__ bind(&jump_table_[i].label);
|
255
|
+
__ Jump(jump_table_[i].address, RelocInfo::RUNTIME_ENTRY);
|
256
|
+
}
|
257
|
+
return !is_aborted();
|
258
|
+
}
|
259
|
+
|
260
|
+
|
243
261
|
bool LCodeGen::GenerateDeferredCode() {
|
244
262
|
ASSERT(is_generating());
|
245
263
|
for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
|
@@ -440,7 +458,7 @@ void LCodeGen::CallCode(Handle<Code> code,
|
|
440
458
|
}
|
441
459
|
|
442
460
|
|
443
|
-
void LCodeGen::CallRuntime(Runtime::Function* function,
|
461
|
+
void LCodeGen::CallRuntime(const Runtime::Function* function,
|
444
462
|
int num_arguments,
|
445
463
|
LInstruction* instr) {
|
446
464
|
ASSERT(instr != NULL);
|
@@ -512,10 +530,13 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
|
|
512
530
|
if (cc == no_condition) {
|
513
531
|
__ Jump(entry, RelocInfo::RUNTIME_ENTRY);
|
514
532
|
} else {
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
533
|
+
// We often have several deopts to the same entry, reuse the last
|
534
|
+
// jump entry if this is the case.
|
535
|
+
if (jump_table_.is_empty() ||
|
536
|
+
jump_table_.last().address != entry) {
|
537
|
+
jump_table_.Add(entry);
|
538
|
+
}
|
539
|
+
__ j(cc, &jump_table_.last().label);
|
519
540
|
}
|
520
541
|
}
|
521
542
|
|
@@ -525,13 +546,14 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
|
|
525
546
|
if (length == 0) return;
|
526
547
|
ASSERT(FLAG_deopt);
|
527
548
|
Handle<DeoptimizationInputData> data =
|
528
|
-
|
549
|
+
factory()->NewDeoptimizationInputData(length, TENURED);
|
529
550
|
|
530
|
-
|
551
|
+
Handle<ByteArray> translations = translations_.CreateByteArray();
|
552
|
+
data->SetTranslationByteArray(*translations);
|
531
553
|
data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
|
532
554
|
|
533
555
|
Handle<FixedArray> literals =
|
534
|
-
|
556
|
+
factory()->NewFixedArray(deoptimization_literals_.length(), TENURED);
|
535
557
|
for (int i = 0; i < deoptimization_literals_.length(); i++) {
|
536
558
|
literals->set(i, *deoptimization_literals_[i]);
|
537
559
|
}
|
@@ -685,16 +707,6 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
|
|
685
707
|
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
686
708
|
break;
|
687
709
|
}
|
688
|
-
case CodeStub::StringCharAt: {
|
689
|
-
// TODO(1116): Add StringCharAt stub to x64.
|
690
|
-
Abort("Unimplemented: %s", "StringCharAt Stub");
|
691
|
-
break;
|
692
|
-
}
|
693
|
-
case CodeStub::MathPow: {
|
694
|
-
// TODO(1115): Add MathPow stub to x64.
|
695
|
-
Abort("Unimplemented: %s", "MathPow Stub");
|
696
|
-
break;
|
697
|
-
}
|
698
710
|
case CodeStub::NumberToString: {
|
699
711
|
NumberToStringStub stub;
|
700
712
|
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
@@ -711,7 +723,8 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
|
|
711
723
|
break;
|
712
724
|
}
|
713
725
|
case CodeStub::TranscendentalCache: {
|
714
|
-
TranscendentalCacheStub stub(instr->transcendental_type()
|
726
|
+
TranscendentalCacheStub stub(instr->transcendental_type(),
|
727
|
+
TranscendentalCacheStub::TAGGED);
|
715
728
|
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
716
729
|
break;
|
717
730
|
}
|
@@ -727,41 +740,65 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
|
|
727
740
|
|
728
741
|
|
729
742
|
void LCodeGen::DoModI(LModI* instr) {
|
730
|
-
|
731
|
-
|
732
|
-
ASSERT(ToRegister(instr->InputAt(0)).is(rax));
|
733
|
-
ASSERT(!ToRegister(instr->InputAt(1)).is(rax));
|
734
|
-
ASSERT(!ToRegister(instr->InputAt(1)).is(rdx));
|
743
|
+
if (instr->hydrogen()->HasPowerOf2Divisor()) {
|
744
|
+
Register dividend = ToRegister(instr->InputAt(0));
|
735
745
|
|
736
|
-
|
746
|
+
int32_t divisor =
|
747
|
+
HConstant::cast(instr->hydrogen()->right())->Integer32Value();
|
737
748
|
|
738
|
-
|
739
|
-
if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
|
740
|
-
__ testl(right_reg, right_reg);
|
741
|
-
DeoptimizeIf(zero, instr->environment());
|
742
|
-
}
|
749
|
+
if (divisor < 0) divisor = -divisor;
|
743
750
|
|
744
|
-
|
745
|
-
|
751
|
+
NearLabel positive_dividend, done;
|
752
|
+
__ testl(dividend, dividend);
|
753
|
+
__ j(not_sign, &positive_dividend);
|
754
|
+
__ negl(dividend);
|
755
|
+
__ andl(dividend, Immediate(divisor - 1));
|
756
|
+
__ negl(dividend);
|
757
|
+
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
758
|
+
__ j(not_zero, &done);
|
759
|
+
DeoptimizeIf(no_condition, instr->environment());
|
760
|
+
}
|
761
|
+
__ bind(&positive_dividend);
|
762
|
+
__ andl(dividend, Immediate(divisor - 1));
|
763
|
+
__ bind(&done);
|
764
|
+
} else {
|
765
|
+
LOperand* right = instr->InputAt(1);
|
766
|
+
Register right_reg = ToRegister(right);
|
767
|
+
|
768
|
+
ASSERT(ToRegister(instr->result()).is(rdx));
|
769
|
+
ASSERT(ToRegister(instr->InputAt(0)).is(rax));
|
770
|
+
ASSERT(!right_reg.is(rax));
|
771
|
+
ASSERT(!right_reg.is(rdx));
|
772
|
+
|
773
|
+
// Check for x % 0.
|
774
|
+
if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
|
775
|
+
__ testl(right_reg, right_reg);
|
776
|
+
DeoptimizeIf(zero, instr->environment());
|
777
|
+
}
|
746
778
|
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
NearLabel done;
|
751
|
-
__ testl(rax, rax);
|
752
|
-
__ j(not_sign, &positive_left);
|
753
|
-
__ idivl(right_reg);
|
779
|
+
// Sign extend eax to edx.
|
780
|
+
// (We are using only the low 32 bits of the values.)
|
781
|
+
__ cdq();
|
754
782
|
|
755
|
-
//
|
756
|
-
|
757
|
-
|
783
|
+
// Check for (0 % -x) that will produce negative zero.
|
784
|
+
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
785
|
+
NearLabel positive_left;
|
786
|
+
NearLabel done;
|
787
|
+
__ testl(rax, rax);
|
788
|
+
__ j(not_sign, &positive_left);
|
789
|
+
__ idivl(right_reg);
|
758
790
|
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
791
|
+
// Test the remainder for 0, because then the result would be -0.
|
792
|
+
__ testl(rdx, rdx);
|
793
|
+
__ j(not_zero, &done);
|
794
|
+
|
795
|
+
DeoptimizeIf(no_condition, instr->environment());
|
796
|
+
__ bind(&positive_left);
|
797
|
+
__ idivl(right_reg);
|
798
|
+
__ bind(&done);
|
799
|
+
} else {
|
800
|
+
__ idivl(right_reg);
|
801
|
+
}
|
765
802
|
}
|
766
803
|
}
|
767
804
|
|
@@ -820,16 +857,56 @@ void LCodeGen::DoMulI(LMulI* instr) {
|
|
820
857
|
__ movl(kScratchRegister, left);
|
821
858
|
}
|
822
859
|
|
860
|
+
bool can_overflow =
|
861
|
+
instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
|
823
862
|
if (right->IsConstantOperand()) {
|
824
863
|
int right_value = ToInteger32(LConstantOperand::cast(right));
|
825
|
-
|
864
|
+
if (right_value == -1) {
|
865
|
+
__ negl(left);
|
866
|
+
} else if (right_value == 0) {
|
867
|
+
__ xorl(left, left);
|
868
|
+
} else if (right_value == 2) {
|
869
|
+
__ addl(left, left);
|
870
|
+
} else if (!can_overflow) {
|
871
|
+
// If the multiplication is known to not overflow, we
|
872
|
+
// can use operations that don't set the overflow flag
|
873
|
+
// correctly.
|
874
|
+
switch (right_value) {
|
875
|
+
case 1:
|
876
|
+
// Do nothing.
|
877
|
+
break;
|
878
|
+
case 3:
|
879
|
+
__ leal(left, Operand(left, left, times_2, 0));
|
880
|
+
break;
|
881
|
+
case 4:
|
882
|
+
__ shll(left, Immediate(2));
|
883
|
+
break;
|
884
|
+
case 5:
|
885
|
+
__ leal(left, Operand(left, left, times_4, 0));
|
886
|
+
break;
|
887
|
+
case 8:
|
888
|
+
__ shll(left, Immediate(3));
|
889
|
+
break;
|
890
|
+
case 9:
|
891
|
+
__ leal(left, Operand(left, left, times_8, 0));
|
892
|
+
break;
|
893
|
+
case 16:
|
894
|
+
__ shll(left, Immediate(4));
|
895
|
+
break;
|
896
|
+
default:
|
897
|
+
__ imull(left, left, Immediate(right_value));
|
898
|
+
break;
|
899
|
+
}
|
900
|
+
} else {
|
901
|
+
__ imull(left, left, Immediate(right_value));
|
902
|
+
}
|
826
903
|
} else if (right->IsStackSlot()) {
|
827
904
|
__ imull(left, ToOperand(right));
|
828
905
|
} else {
|
829
906
|
__ imull(left, ToRegister(right));
|
830
907
|
}
|
831
908
|
|
832
|
-
if (
|
909
|
+
if (can_overflow) {
|
833
910
|
DeoptimizeIf(overflow, instr->environment());
|
834
911
|
}
|
835
912
|
|
@@ -1031,10 +1108,10 @@ void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
|
|
1031
1108
|
}
|
1032
1109
|
|
1033
1110
|
|
1034
|
-
void LCodeGen::
|
1111
|
+
void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) {
|
1035
1112
|
Register result = ToRegister(instr->result());
|
1036
1113
|
Register array = ToRegister(instr->InputAt(0));
|
1037
|
-
__
|
1114
|
+
__ movl(result, FieldOperand(array, ExternalPixelArray::kLengthOffset));
|
1038
1115
|
}
|
1039
1116
|
|
1040
1117
|
|
@@ -1094,25 +1171,32 @@ void LCodeGen::DoAddI(LAddI* instr) {
|
|
1094
1171
|
|
1095
1172
|
|
1096
1173
|
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
|
1097
|
-
|
1098
|
-
|
1174
|
+
XMMRegister left = ToDoubleRegister(instr->InputAt(0));
|
1175
|
+
XMMRegister right = ToDoubleRegister(instr->InputAt(1));
|
1176
|
+
XMMRegister result = ToDoubleRegister(instr->result());
|
1099
1177
|
// All operations except MOD are computed in-place.
|
1100
|
-
ASSERT(instr->op() == Token::MOD || left
|
1178
|
+
ASSERT(instr->op() == Token::MOD || left.is(result));
|
1101
1179
|
switch (instr->op()) {
|
1102
1180
|
case Token::ADD:
|
1103
|
-
__ addsd(
|
1181
|
+
__ addsd(left, right);
|
1104
1182
|
break;
|
1105
1183
|
case Token::SUB:
|
1106
|
-
__ subsd(
|
1184
|
+
__ subsd(left, right);
|
1107
1185
|
break;
|
1108
1186
|
case Token::MUL:
|
1109
|
-
__ mulsd(
|
1187
|
+
__ mulsd(left, right);
|
1110
1188
|
break;
|
1111
1189
|
case Token::DIV:
|
1112
|
-
__ divsd(
|
1190
|
+
__ divsd(left, right);
|
1113
1191
|
break;
|
1114
1192
|
case Token::MOD:
|
1115
|
-
|
1193
|
+
__ PrepareCallCFunction(2);
|
1194
|
+
__ movsd(xmm0, left);
|
1195
|
+
ASSERT(right.is(xmm1));
|
1196
|
+
__ CallCFunction(
|
1197
|
+
ExternalReference::double_fp_operation(Token::MOD, isolate()), 2);
|
1198
|
+
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
1199
|
+
__ movsd(result, xmm0);
|
1116
1200
|
break;
|
1117
1201
|
default:
|
1118
1202
|
UNREACHABLE();
|
@@ -1179,7 +1263,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
|
1179
1263
|
Register reg = ToRegister(instr->InputAt(0));
|
1180
1264
|
HType type = instr->hydrogen()->type();
|
1181
1265
|
if (type.IsBoolean()) {
|
1182
|
-
__
|
1266
|
+
__ CompareRoot(reg, Heap::kTrueValueRootIndex);
|
1183
1267
|
EmitBranch(true_block, false_block, equal);
|
1184
1268
|
} else if (type.IsSmi()) {
|
1185
1269
|
__ SmiCompare(reg, Smi::FromInt(0));
|
@@ -1194,7 +1278,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
|
1194
1278
|
__ j(equal, true_label);
|
1195
1279
|
__ CompareRoot(reg, Heap::kFalseValueRootIndex);
|
1196
1280
|
__ j(equal, false_label);
|
1197
|
-
__
|
1281
|
+
__ Cmp(reg, Smi::FromInt(0));
|
1198
1282
|
__ j(equal, false_label);
|
1199
1283
|
__ JumpIfSmi(reg, true_label);
|
1200
1284
|
|
@@ -1406,7 +1490,7 @@ void LCodeGen::DoIsNull(LIsNull* instr) {
|
|
1406
1490
|
__ j(equal, &load);
|
1407
1491
|
__ movl(result, Immediate(Heap::kFalseValueRootIndex));
|
1408
1492
|
__ bind(&load);
|
1409
|
-
__
|
1493
|
+
__ LoadRootIndexed(result, result, 0);
|
1410
1494
|
} else {
|
1411
1495
|
NearLabel true_value, false_value, done;
|
1412
1496
|
__ j(equal, &true_value);
|
@@ -1446,14 +1530,14 @@ void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
|
|
1446
1530
|
|
1447
1531
|
int true_block = chunk_->LookupDestination(instr->true_block_id());
|
1448
1532
|
|
1449
|
-
__
|
1533
|
+
__ CompareRoot(reg, Heap::kNullValueRootIndex);
|
1450
1534
|
if (instr->is_strict()) {
|
1451
1535
|
EmitBranch(true_block, false_block, equal);
|
1452
1536
|
} else {
|
1453
1537
|
Label* true_label = chunk_->GetAssemblyLabel(true_block);
|
1454
1538
|
Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
1455
1539
|
__ j(equal, true_label);
|
1456
|
-
__
|
1540
|
+
__ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
|
1457
1541
|
__ j(equal, true_label);
|
1458
1542
|
__ JumpIfSmi(reg, false_label);
|
1459
1543
|
// Check for undetectable objects by looking in the bit field in
|
@@ -1537,8 +1621,7 @@ void LCodeGen::DoIsSmi(LIsSmi* instr) {
|
|
1537
1621
|
}
|
1538
1622
|
// result is zero if input is a smi, and one otherwise.
|
1539
1623
|
ASSERT(Heap::kFalseValueRootIndex == Heap::kTrueValueRootIndex + 1);
|
1540
|
-
__
|
1541
|
-
Heap::kTrueValueRootIndex * kPointerSize));
|
1624
|
+
__ LoadRootIndexed(result, result, Heap::kTrueValueRootIndex);
|
1542
1625
|
}
|
1543
1626
|
|
1544
1627
|
|
@@ -1579,7 +1662,20 @@ static Condition BranchCondition(HHasInstanceType* instr) {
|
|
1579
1662
|
|
1580
1663
|
|
1581
1664
|
void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
|
1582
|
-
|
1665
|
+
Register input = ToRegister(instr->InputAt(0));
|
1666
|
+
Register result = ToRegister(instr->result());
|
1667
|
+
|
1668
|
+
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
|
1669
|
+
__ testl(input, Immediate(kSmiTagMask));
|
1670
|
+
NearLabel done, is_false;
|
1671
|
+
__ j(zero, &is_false);
|
1672
|
+
__ CmpObjectType(input, TestType(instr->hydrogen()), result);
|
1673
|
+
__ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
|
1674
|
+
__ LoadRoot(result, Heap::kTrueValueRootIndex);
|
1675
|
+
__ jmp(&done);
|
1676
|
+
__ bind(&is_false);
|
1677
|
+
__ LoadRoot(result, Heap::kFalseValueRootIndex);
|
1678
|
+
__ bind(&done);
|
1583
1679
|
}
|
1584
1680
|
|
1585
1681
|
|
@@ -1598,8 +1694,32 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
|
|
1598
1694
|
}
|
1599
1695
|
|
1600
1696
|
|
1697
|
+
void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
|
1698
|
+
Register input = ToRegister(instr->InputAt(0));
|
1699
|
+
Register result = ToRegister(instr->result());
|
1700
|
+
|
1701
|
+
if (FLAG_debug_code) {
|
1702
|
+
__ AbortIfNotString(input);
|
1703
|
+
}
|
1704
|
+
|
1705
|
+
__ movl(result, FieldOperand(input, String::kHashFieldOffset));
|
1706
|
+
ASSERT(String::kHashShift >= kSmiTagSize);
|
1707
|
+
__ IndexFromHash(result, result);
|
1708
|
+
}
|
1709
|
+
|
1710
|
+
|
1601
1711
|
void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
|
1602
|
-
|
1712
|
+
Register input = ToRegister(instr->InputAt(0));
|
1713
|
+
Register result = ToRegister(instr->result());
|
1714
|
+
|
1715
|
+
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
|
1716
|
+
__ LoadRoot(result, Heap::kTrueValueRootIndex);
|
1717
|
+
__ testl(FieldOperand(input, String::kHashFieldOffset),
|
1718
|
+
Immediate(String::kContainsCachedArrayIndexMask));
|
1719
|
+
NearLabel done;
|
1720
|
+
__ j(zero, &done);
|
1721
|
+
__ LoadRoot(result, Heap::kFalseValueRootIndex);
|
1722
|
+
__ bind(&done);
|
1603
1723
|
}
|
1604
1724
|
|
1605
1725
|
|
@@ -1612,7 +1732,7 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
|
|
1612
1732
|
|
1613
1733
|
__ testl(FieldOperand(input, String::kHashFieldOffset),
|
1614
1734
|
Immediate(String::kContainsCachedArrayIndexMask));
|
1615
|
-
EmitBranch(true_block, false_block,
|
1735
|
+
EmitBranch(true_block, false_block, equal);
|
1616
1736
|
}
|
1617
1737
|
|
1618
1738
|
|
@@ -1756,24 +1876,51 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
|
|
1756
1876
|
LInstanceOfKnownGlobal* instr)
|
1757
1877
|
: LDeferredCode(codegen), instr_(instr) { }
|
1758
1878
|
virtual void Generate() {
|
1759
|
-
codegen()->DoDeferredLInstanceOfKnownGlobal(instr_);
|
1879
|
+
codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_);
|
1760
1880
|
}
|
1761
1881
|
|
1882
|
+
Label* map_check() { return &map_check_; }
|
1883
|
+
|
1762
1884
|
private:
|
1763
1885
|
LInstanceOfKnownGlobal* instr_;
|
1886
|
+
Label map_check_;
|
1764
1887
|
};
|
1765
1888
|
|
1766
1889
|
|
1767
1890
|
DeferredInstanceOfKnownGlobal* deferred;
|
1768
1891
|
deferred = new DeferredInstanceOfKnownGlobal(this, instr);
|
1769
1892
|
|
1770
|
-
Label false_result;
|
1893
|
+
Label done, false_result;
|
1771
1894
|
Register object = ToRegister(instr->InputAt(0));
|
1772
1895
|
|
1773
1896
|
// A Smi is not an instance of anything.
|
1774
1897
|
__ JumpIfSmi(object, &false_result);
|
1775
1898
|
|
1776
|
-
//
|
1899
|
+
// This is the inlined call site instanceof cache. The two occurences of the
|
1900
|
+
// hole value will be patched to the last map/result pair generated by the
|
1901
|
+
// instanceof stub.
|
1902
|
+
NearLabel cache_miss;
|
1903
|
+
// Use a temp register to avoid memory operands with variable lengths.
|
1904
|
+
Register map = ToRegister(instr->TempAt(0));
|
1905
|
+
__ movq(map, FieldOperand(object, HeapObject::kMapOffset));
|
1906
|
+
__ bind(deferred->map_check()); // Label for calculating code patching.
|
1907
|
+
__ movq(kScratchRegister, factory()->the_hole_value(),
|
1908
|
+
RelocInfo::EMBEDDED_OBJECT);
|
1909
|
+
__ cmpq(map, kScratchRegister); // Patched to cached map.
|
1910
|
+
__ j(not_equal, &cache_miss);
|
1911
|
+
// Patched to load either true or false.
|
1912
|
+
__ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
|
1913
|
+
#ifdef DEBUG
|
1914
|
+
// Check that the code size between patch label and patch sites is invariant.
|
1915
|
+
Label end_of_patched_code;
|
1916
|
+
__ bind(&end_of_patched_code);
|
1917
|
+
ASSERT(true);
|
1918
|
+
#endif
|
1919
|
+
__ jmp(&done);
|
1920
|
+
|
1921
|
+
// The inlined call site cache did not match. Check for null and string
|
1922
|
+
// before calling the deferred code.
|
1923
|
+
__ bind(&cache_miss); // Null is not an instance of anything.
|
1777
1924
|
__ CompareRoot(object, Heap::kNullValueRootIndex);
|
1778
1925
|
__ j(equal, &false_result);
|
1779
1926
|
|
@@ -1784,20 +1931,27 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
|
|
1784
1931
|
__ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
|
1785
1932
|
|
1786
1933
|
__ bind(deferred->exit());
|
1934
|
+
__ bind(&done);
|
1787
1935
|
}
|
1788
1936
|
|
1789
1937
|
|
1790
|
-
void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr
|
1938
|
+
void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
|
1939
|
+
Label* map_check) {
|
1791
1940
|
__ PushSafepointRegisters();
|
1792
|
-
|
1793
|
-
|
1941
|
+
InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
|
1942
|
+
InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck);
|
1943
|
+
InstanceofStub stub(flags);
|
1794
1944
|
|
1795
1945
|
__ push(ToRegister(instr->InputAt(0)));
|
1796
1946
|
__ Push(instr->function());
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1947
|
+
Register temp = ToRegister(instr->TempAt(0));
|
1948
|
+
ASSERT(temp.is(rdi));
|
1949
|
+
static const int kAdditionalDelta = 16;
|
1950
|
+
int delta =
|
1951
|
+
masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
|
1952
|
+
__ movq(temp, Immediate(delta));
|
1953
|
+
__ push(temp);
|
1954
|
+
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
1801
1955
|
__ movq(kScratchRegister, rax);
|
1802
1956
|
__ PopSafepointRegisters();
|
1803
1957
|
__ testq(kScratchRegister, kScratchRegister);
|
@@ -1865,7 +2019,7 @@ void LCodeGen::DoReturn(LReturn* instr) {
|
|
1865
2019
|
}
|
1866
2020
|
|
1867
2021
|
|
1868
|
-
void LCodeGen::
|
2022
|
+
void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
|
1869
2023
|
Register result = ToRegister(instr->result());
|
1870
2024
|
if (result.is(rax)) {
|
1871
2025
|
__ load_rax(instr->hydrogen()->cell().location(),
|
@@ -1881,6 +2035,18 @@ void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) {
|
|
1881
2035
|
}
|
1882
2036
|
|
1883
2037
|
|
2038
|
+
void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
|
2039
|
+
ASSERT(ToRegister(instr->global_object()).is(rax));
|
2040
|
+
ASSERT(ToRegister(instr->result()).is(rax));
|
2041
|
+
|
2042
|
+
__ Move(rcx, instr->name());
|
2043
|
+
RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET :
|
2044
|
+
RelocInfo::CODE_TARGET_CONTEXT;
|
2045
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
2046
|
+
CallCode(ic, mode, instr);
|
2047
|
+
}
|
2048
|
+
|
2049
|
+
|
1884
2050
|
void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
|
1885
2051
|
Register value = ToRegister(instr->InputAt(0));
|
1886
2052
|
Register temp = ToRegister(instr->TempAt(0));
|
@@ -1917,7 +2083,8 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
|
|
1917
2083
|
__ movq(ContextOperand(context, instr->slot_index()), value);
|
1918
2084
|
if (instr->needs_write_barrier()) {
|
1919
2085
|
int offset = Context::SlotOffset(instr->slot_index());
|
1920
|
-
|
2086
|
+
Register scratch = ToRegister(instr->TempAt(0));
|
2087
|
+
__ RecordWrite(context, offset, value, scratch);
|
1921
2088
|
}
|
1922
2089
|
}
|
1923
2090
|
|
@@ -1934,12 +2101,76 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
|
|
1934
2101
|
}
|
1935
2102
|
|
1936
2103
|
|
2104
|
+
void LCodeGen::EmitLoadField(Register result,
|
2105
|
+
Register object,
|
2106
|
+
Handle<Map> type,
|
2107
|
+
Handle<String> name) {
|
2108
|
+
LookupResult lookup;
|
2109
|
+
type->LookupInDescriptors(NULL, *name, &lookup);
|
2110
|
+
ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
|
2111
|
+
int index = lookup.GetLocalFieldIndexFromMap(*type);
|
2112
|
+
int offset = index * kPointerSize;
|
2113
|
+
if (index < 0) {
|
2114
|
+
// Negative property indices are in-object properties, indexed
|
2115
|
+
// from the end of the fixed part of the object.
|
2116
|
+
__ movq(result, FieldOperand(object, offset + type->instance_size()));
|
2117
|
+
} else {
|
2118
|
+
// Non-negative property indices are in the properties array.
|
2119
|
+
__ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
|
2120
|
+
__ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
|
2121
|
+
}
|
2122
|
+
}
|
2123
|
+
|
2124
|
+
|
2125
|
+
void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
|
2126
|
+
Register object = ToRegister(instr->object());
|
2127
|
+
Register result = ToRegister(instr->result());
|
2128
|
+
|
2129
|
+
int map_count = instr->hydrogen()->types()->length();
|
2130
|
+
Handle<String> name = instr->hydrogen()->name();
|
2131
|
+
|
2132
|
+
if (map_count == 0) {
|
2133
|
+
ASSERT(instr->hydrogen()->need_generic());
|
2134
|
+
__ Move(rcx, instr->hydrogen()->name());
|
2135
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
2136
|
+
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2137
|
+
} else {
|
2138
|
+
NearLabel done;
|
2139
|
+
for (int i = 0; i < map_count - 1; ++i) {
|
2140
|
+
Handle<Map> map = instr->hydrogen()->types()->at(i);
|
2141
|
+
NearLabel next;
|
2142
|
+
__ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
|
2143
|
+
__ j(not_equal, &next);
|
2144
|
+
EmitLoadField(result, object, map, name);
|
2145
|
+
__ jmp(&done);
|
2146
|
+
__ bind(&next);
|
2147
|
+
}
|
2148
|
+
Handle<Map> map = instr->hydrogen()->types()->last();
|
2149
|
+
__ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
|
2150
|
+
if (instr->hydrogen()->need_generic()) {
|
2151
|
+
NearLabel generic;
|
2152
|
+
__ j(not_equal, &generic);
|
2153
|
+
EmitLoadField(result, object, map, name);
|
2154
|
+
__ jmp(&done);
|
2155
|
+
__ bind(&generic);
|
2156
|
+
__ Move(rcx, instr->hydrogen()->name());
|
2157
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
2158
|
+
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2159
|
+
} else {
|
2160
|
+
DeoptimizeIf(not_equal, instr->environment());
|
2161
|
+
EmitLoadField(result, object, map, name);
|
2162
|
+
}
|
2163
|
+
__ bind(&done);
|
2164
|
+
}
|
2165
|
+
}
|
2166
|
+
|
2167
|
+
|
1937
2168
|
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
1938
2169
|
ASSERT(ToRegister(instr->object()).is(rax));
|
1939
2170
|
ASSERT(ToRegister(instr->result()).is(rax));
|
1940
2171
|
|
1941
2172
|
__ Move(rcx, instr->name());
|
1942
|
-
Handle<Code> ic(
|
2173
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
1943
2174
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
1944
2175
|
}
|
1945
2176
|
|
@@ -1991,25 +2222,31 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
|
|
1991
2222
|
__ movq(result, FieldOperand(input, JSObject::kElementsOffset));
|
1992
2223
|
if (FLAG_debug_code) {
|
1993
2224
|
NearLabel done;
|
1994
|
-
__
|
1995
|
-
|
2225
|
+
__ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
|
2226
|
+
Heap::kFixedArrayMapRootIndex);
|
1996
2227
|
__ j(equal, &done);
|
1997
|
-
__
|
1998
|
-
|
2228
|
+
__ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
|
2229
|
+
Heap::kFixedCOWArrayMapRootIndex);
|
1999
2230
|
__ j(equal, &done);
|
2000
|
-
|
2001
|
-
|
2002
|
-
__
|
2231
|
+
Register temp((result.is(rax)) ? rbx : rax);
|
2232
|
+
__ push(temp);
|
2233
|
+
__ movq(temp, FieldOperand(result, HeapObject::kMapOffset));
|
2234
|
+
__ movzxbq(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
|
2235
|
+
__ subq(temp, Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
|
2236
|
+
__ cmpq(temp, Immediate(kExternalArrayTypeCount));
|
2237
|
+
__ pop(temp);
|
2238
|
+
__ Check(below, "Check for fast elements failed.");
|
2003
2239
|
__ bind(&done);
|
2004
2240
|
}
|
2005
2241
|
}
|
2006
2242
|
|
2007
2243
|
|
2008
|
-
void LCodeGen::
|
2009
|
-
|
2244
|
+
void LCodeGen::DoLoadExternalArrayPointer(
|
2245
|
+
LLoadExternalArrayPointer* instr) {
|
2010
2246
|
Register result = ToRegister(instr->result());
|
2011
2247
|
Register input = ToRegister(instr->InputAt(0));
|
2012
|
-
__ movq(result, FieldOperand(input,
|
2248
|
+
__ movq(result, FieldOperand(input,
|
2249
|
+
ExternalPixelArray::kExternalPointerOffset));
|
2013
2250
|
}
|
2014
2251
|
|
2015
2252
|
|
@@ -2044,19 +2281,52 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
|
|
2044
2281
|
FixedArray::kHeaderSize));
|
2045
2282
|
|
2046
2283
|
// Check for the hole value.
|
2047
|
-
__
|
2284
|
+
__ CompareRoot(result, Heap::kTheHoleValueRootIndex);
|
2048
2285
|
DeoptimizeIf(equal, instr->environment());
|
2049
2286
|
}
|
2050
2287
|
|
2051
2288
|
|
2052
|
-
void LCodeGen::
|
2053
|
-
|
2289
|
+
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
|
2290
|
+
LLoadKeyedSpecializedArrayElement* instr) {
|
2291
|
+
Register external_pointer = ToRegister(instr->external_pointer());
|
2054
2292
|
Register key = ToRegister(instr->key());
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2293
|
+
ExternalArrayType array_type = instr->array_type();
|
2294
|
+
if (array_type == kExternalFloatArray) {
|
2295
|
+
XMMRegister result(ToDoubleRegister(instr->result()));
|
2296
|
+
__ movss(result, Operand(external_pointer, key, times_4, 0));
|
2297
|
+
__ cvtss2sd(result, result);
|
2298
|
+
} else {
|
2299
|
+
Register result(ToRegister(instr->result()));
|
2300
|
+
switch (array_type) {
|
2301
|
+
case kExternalByteArray:
|
2302
|
+
__ movsxbq(result, Operand(external_pointer, key, times_1, 0));
|
2303
|
+
break;
|
2304
|
+
case kExternalUnsignedByteArray:
|
2305
|
+
case kExternalPixelArray:
|
2306
|
+
__ movzxbq(result, Operand(external_pointer, key, times_1, 0));
|
2307
|
+
break;
|
2308
|
+
case kExternalShortArray:
|
2309
|
+
__ movsxwq(result, Operand(external_pointer, key, times_2, 0));
|
2310
|
+
break;
|
2311
|
+
case kExternalUnsignedShortArray:
|
2312
|
+
__ movzxwq(result, Operand(external_pointer, key, times_2, 0));
|
2313
|
+
break;
|
2314
|
+
case kExternalIntArray:
|
2315
|
+
__ movsxlq(result, Operand(external_pointer, key, times_4, 0));
|
2316
|
+
break;
|
2317
|
+
case kExternalUnsignedIntArray:
|
2318
|
+
__ movl(result, Operand(external_pointer, key, times_4, 0));
|
2319
|
+
__ testl(result, result);
|
2320
|
+
// TODO(danno): we could be more clever here, perhaps having a special
|
2321
|
+
// version of the stub that detects if the overflow case actually
|
2322
|
+
// happens, and generate code that returns a double rather than int.
|
2323
|
+
DeoptimizeIf(negative, instr->environment());
|
2324
|
+
break;
|
2325
|
+
case kExternalFloatArray:
|
2326
|
+
UNREACHABLE();
|
2327
|
+
break;
|
2328
|
+
}
|
2329
|
+
}
|
2060
2330
|
}
|
2061
2331
|
|
2062
2332
|
|
@@ -2064,7 +2334,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
|
|
2064
2334
|
ASSERT(ToRegister(instr->object()).is(rdx));
|
2065
2335
|
ASSERT(ToRegister(instr->key()).is(rax));
|
2066
2336
|
|
2067
|
-
Handle<Code> ic(
|
2337
|
+
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
|
2068
2338
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2069
2339
|
}
|
2070
2340
|
|
@@ -2075,8 +2345,8 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
|
|
2075
2345
|
// Check for arguments adapter frame.
|
2076
2346
|
NearLabel done, adapted;
|
2077
2347
|
__ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
2078
|
-
__
|
2079
|
-
|
2348
|
+
__ Cmp(Operand(result, StandardFrameConstants::kContextOffset),
|
2349
|
+
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
2080
2350
|
__ j(equal, &adapted);
|
2081
2351
|
|
2082
2352
|
// No arguments adaptor frame.
|
@@ -2179,8 +2449,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
|
|
2179
2449
|
RegisterEnvironmentForDeoptimization(env);
|
2180
2450
|
SafepointGenerator safepoint_generator(this,
|
2181
2451
|
pointers,
|
2182
|
-
env->deoptimization_index()
|
2183
|
-
true);
|
2452
|
+
env->deoptimization_index());
|
2184
2453
|
v8::internal::ParameterCount actual(rax);
|
2185
2454
|
__ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
|
2186
2455
|
}
|
@@ -2221,9 +2490,9 @@ void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
|
|
2221
2490
|
|
2222
2491
|
|
2223
2492
|
void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
|
2493
|
+
Register global = ToRegister(instr->global());
|
2224
2494
|
Register result = ToRegister(instr->result());
|
2225
|
-
__ movq(result,
|
2226
|
-
__ movq(result, FieldOperand(result, GlobalObject::kGlobalReceiverOffset));
|
2495
|
+
__ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset));
|
2227
2496
|
}
|
2228
2497
|
|
2229
2498
|
|
@@ -2232,7 +2501,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
|
2232
2501
|
LInstruction* instr) {
|
2233
2502
|
// Change context if needed.
|
2234
2503
|
bool change_context =
|
2235
|
-
(
|
2504
|
+
(info()->closure()->context() != function->context()) ||
|
2236
2505
|
scope()->contains_with() ||
|
2237
2506
|
(scope()->num_heap_slots() > 0);
|
2238
2507
|
if (change_context) {
|
@@ -2249,7 +2518,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
|
2249
2518
|
RecordPosition(pointers->position());
|
2250
2519
|
|
2251
2520
|
// Invoke function.
|
2252
|
-
if (*function == *
|
2521
|
+
if (*function == *info()->closure()) {
|
2253
2522
|
__ CallSelf();
|
2254
2523
|
} else {
|
2255
2524
|
__ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset));
|
@@ -2271,12 +2540,105 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
|
|
2271
2540
|
|
2272
2541
|
|
2273
2542
|
void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
|
2274
|
-
|
2543
|
+
Register input_reg = ToRegister(instr->InputAt(0));
|
2544
|
+
__ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
|
2545
|
+
Heap::kHeapNumberMapRootIndex);
|
2546
|
+
DeoptimizeIf(not_equal, instr->environment());
|
2547
|
+
|
2548
|
+
Label done;
|
2549
|
+
Register tmp = input_reg.is(rax) ? rcx : rax;
|
2550
|
+
Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx;
|
2551
|
+
|
2552
|
+
// Preserve the value of all registers.
|
2553
|
+
__ PushSafepointRegisters();
|
2554
|
+
|
2555
|
+
Label negative;
|
2556
|
+
__ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset));
|
2557
|
+
// Check the sign of the argument. If the argument is positive, just
|
2558
|
+
// return it. We do not need to patch the stack since |input| and
|
2559
|
+
// |result| are the same register and |input| will be restored
|
2560
|
+
// unchanged by popping safepoint registers.
|
2561
|
+
__ testl(tmp, Immediate(HeapNumber::kSignMask));
|
2562
|
+
__ j(not_zero, &negative);
|
2563
|
+
__ jmp(&done);
|
2564
|
+
|
2565
|
+
__ bind(&negative);
|
2566
|
+
|
2567
|
+
Label allocated, slow;
|
2568
|
+
__ AllocateHeapNumber(tmp, tmp2, &slow);
|
2569
|
+
__ jmp(&allocated);
|
2570
|
+
|
2571
|
+
// Slow case: Call the runtime system to do the number allocation.
|
2572
|
+
__ bind(&slow);
|
2573
|
+
|
2574
|
+
__ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
|
2575
|
+
RecordSafepointWithRegisters(
|
2576
|
+
instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
|
2577
|
+
// Set the pointer to the new heap number in tmp.
|
2578
|
+
if (!tmp.is(rax)) {
|
2579
|
+
__ movq(tmp, rax);
|
2580
|
+
}
|
2581
|
+
|
2582
|
+
// Restore input_reg after call to runtime.
|
2583
|
+
__ LoadFromSafepointRegisterSlot(input_reg, input_reg);
|
2584
|
+
|
2585
|
+
__ bind(&allocated);
|
2586
|
+
__ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
2587
|
+
__ shl(tmp2, Immediate(1));
|
2588
|
+
__ shr(tmp2, Immediate(1));
|
2589
|
+
__ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
|
2590
|
+
__ StoreToSafepointRegisterSlot(input_reg, tmp);
|
2591
|
+
|
2592
|
+
__ bind(&done);
|
2593
|
+
__ PopSafepointRegisters();
|
2594
|
+
}
|
2595
|
+
|
2596
|
+
|
2597
|
+
void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
|
2598
|
+
Register input_reg = ToRegister(instr->InputAt(0));
|
2599
|
+
__ testl(input_reg, input_reg);
|
2600
|
+
Label is_positive;
|
2601
|
+
__ j(not_sign, &is_positive);
|
2602
|
+
__ negl(input_reg); // Sets flags.
|
2603
|
+
DeoptimizeIf(negative, instr->environment());
|
2604
|
+
__ bind(&is_positive);
|
2275
2605
|
}
|
2276
2606
|
|
2277
2607
|
|
2278
2608
|
void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
|
2279
|
-
|
2609
|
+
// Class for deferred case.
|
2610
|
+
class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
|
2611
|
+
public:
|
2612
|
+
DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
|
2613
|
+
LUnaryMathOperation* instr)
|
2614
|
+
: LDeferredCode(codegen), instr_(instr) { }
|
2615
|
+
virtual void Generate() {
|
2616
|
+
codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
|
2617
|
+
}
|
2618
|
+
private:
|
2619
|
+
LUnaryMathOperation* instr_;
|
2620
|
+
};
|
2621
|
+
|
2622
|
+
ASSERT(instr->InputAt(0)->Equals(instr->result()));
|
2623
|
+
Representation r = instr->hydrogen()->value()->representation();
|
2624
|
+
|
2625
|
+
if (r.IsDouble()) {
|
2626
|
+
XMMRegister scratch = xmm0;
|
2627
|
+
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
|
2628
|
+
__ xorpd(scratch, scratch);
|
2629
|
+
__ subsd(scratch, input_reg);
|
2630
|
+
__ andpd(input_reg, scratch);
|
2631
|
+
} else if (r.IsInteger32()) {
|
2632
|
+
EmitIntegerMathAbs(instr);
|
2633
|
+
} else { // Tagged case.
|
2634
|
+
DeferredMathAbsTaggedHeapNumber* deferred =
|
2635
|
+
new DeferredMathAbsTaggedHeapNumber(this, instr);
|
2636
|
+
Register input_reg = ToRegister(instr->InputAt(0));
|
2637
|
+
// Smi check.
|
2638
|
+
__ JumpIfNotSmi(input_reg, deferred->entry());
|
2639
|
+
EmitIntegerMathAbs(instr);
|
2640
|
+
__ bind(deferred->exit());
|
2641
|
+
}
|
2280
2642
|
}
|
2281
2643
|
|
2282
2644
|
|
@@ -2355,22 +2717,83 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
|
|
2355
2717
|
|
2356
2718
|
|
2357
2719
|
void LCodeGen::DoPower(LPower* instr) {
|
2358
|
-
|
2720
|
+
LOperand* left = instr->InputAt(0);
|
2721
|
+
XMMRegister left_reg = ToDoubleRegister(left);
|
2722
|
+
ASSERT(!left_reg.is(xmm1));
|
2723
|
+
LOperand* right = instr->InputAt(1);
|
2724
|
+
XMMRegister result_reg = ToDoubleRegister(instr->result());
|
2725
|
+
Representation exponent_type = instr->hydrogen()->right()->representation();
|
2726
|
+
if (exponent_type.IsDouble()) {
|
2727
|
+
__ PrepareCallCFunction(2);
|
2728
|
+
// Move arguments to correct registers
|
2729
|
+
__ movsd(xmm0, left_reg);
|
2730
|
+
ASSERT(ToDoubleRegister(right).is(xmm1));
|
2731
|
+
__ CallCFunction(
|
2732
|
+
ExternalReference::power_double_double_function(isolate()), 2);
|
2733
|
+
} else if (exponent_type.IsInteger32()) {
|
2734
|
+
__ PrepareCallCFunction(2);
|
2735
|
+
// Move arguments to correct registers: xmm0 and edi (not rdi).
|
2736
|
+
// On Windows, the registers are xmm0 and edx.
|
2737
|
+
__ movsd(xmm0, left_reg);
|
2738
|
+
#ifdef _WIN64
|
2739
|
+
ASSERT(ToRegister(right).is(rdx));
|
2740
|
+
#else
|
2741
|
+
ASSERT(ToRegister(right).is(rdi));
|
2742
|
+
#endif
|
2743
|
+
__ CallCFunction(
|
2744
|
+
ExternalReference::power_double_int_function(isolate()), 2);
|
2745
|
+
} else {
|
2746
|
+
ASSERT(exponent_type.IsTagged());
|
2747
|
+
CpuFeatures::Scope scope(SSE2);
|
2748
|
+
Register right_reg = ToRegister(right);
|
2749
|
+
|
2750
|
+
Label non_smi, call;
|
2751
|
+
__ JumpIfNotSmi(right_reg, &non_smi);
|
2752
|
+
__ SmiToInteger32(right_reg, right_reg);
|
2753
|
+
__ cvtlsi2sd(xmm1, right_reg);
|
2754
|
+
__ jmp(&call);
|
2755
|
+
|
2756
|
+
__ bind(&non_smi);
|
2757
|
+
__ CmpObjectType(right_reg, HEAP_NUMBER_TYPE , kScratchRegister);
|
2758
|
+
DeoptimizeIf(not_equal, instr->environment());
|
2759
|
+
__ movsd(xmm1, FieldOperand(right_reg, HeapNumber::kValueOffset));
|
2760
|
+
|
2761
|
+
__ bind(&call);
|
2762
|
+
__ PrepareCallCFunction(2);
|
2763
|
+
// Move arguments to correct registers xmm0 and xmm1.
|
2764
|
+
__ movsd(xmm0, left_reg);
|
2765
|
+
// Right argument is already in xmm1.
|
2766
|
+
__ CallCFunction(
|
2767
|
+
ExternalReference::power_double_double_function(isolate()), 2);
|
2768
|
+
}
|
2769
|
+
// Return value is in xmm0.
|
2770
|
+
__ movsd(result_reg, xmm0);
|
2771
|
+
// Restore context register.
|
2772
|
+
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
2359
2773
|
}
|
2360
2774
|
|
2361
2775
|
|
2362
2776
|
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
|
2363
|
-
|
2777
|
+
ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
|
2778
|
+
TranscendentalCacheStub stub(TranscendentalCache::LOG,
|
2779
|
+
TranscendentalCacheStub::UNTAGGED);
|
2780
|
+
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
2364
2781
|
}
|
2365
2782
|
|
2366
2783
|
|
2367
2784
|
void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
|
2368
|
-
|
2785
|
+
ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
|
2786
|
+
TranscendentalCacheStub stub(TranscendentalCache::COS,
|
2787
|
+
TranscendentalCacheStub::UNTAGGED);
|
2788
|
+
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
2369
2789
|
}
|
2370
2790
|
|
2371
2791
|
|
2372
2792
|
void LCodeGen::DoMathSin(LUnaryMathOperation* instr) {
|
2373
|
-
|
2793
|
+
ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
|
2794
|
+
TranscendentalCacheStub stub(TranscendentalCache::SIN,
|
2795
|
+
TranscendentalCacheStub::UNTAGGED);
|
2796
|
+
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
2374
2797
|
}
|
2375
2798
|
|
2376
2799
|
|
@@ -2412,8 +2835,10 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
|
|
2412
2835
|
ASSERT(ToRegister(instr->result()).is(rax));
|
2413
2836
|
|
2414
2837
|
int arity = instr->arity();
|
2415
|
-
Handle<Code> ic =
|
2838
|
+
Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
|
2839
|
+
arity, NOT_IN_LOOP);
|
2416
2840
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2841
|
+
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
2417
2842
|
}
|
2418
2843
|
|
2419
2844
|
|
@@ -2421,7 +2846,8 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) {
|
|
2421
2846
|
ASSERT(ToRegister(instr->result()).is(rax));
|
2422
2847
|
|
2423
2848
|
int arity = instr->arity();
|
2424
|
-
Handle<Code> ic =
|
2849
|
+
Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
|
2850
|
+
arity, NOT_IN_LOOP);
|
2425
2851
|
__ Move(rcx, instr->name());
|
2426
2852
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2427
2853
|
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
@@ -2442,7 +2868,8 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
|
|
2442
2868
|
void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
|
2443
2869
|
ASSERT(ToRegister(instr->result()).is(rax));
|
2444
2870
|
int arity = instr->arity();
|
2445
|
-
Handle<Code> ic =
|
2871
|
+
Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
|
2872
|
+
arity, NOT_IN_LOOP);
|
2446
2873
|
__ Move(rcx, instr->name());
|
2447
2874
|
CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
|
2448
2875
|
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
@@ -2460,7 +2887,7 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
|
|
2460
2887
|
ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
|
2461
2888
|
ASSERT(ToRegister(instr->result()).is(rax));
|
2462
2889
|
|
2463
|
-
Handle<Code> builtin(
|
2890
|
+
Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
|
2464
2891
|
__ Set(rax, instr->arity());
|
2465
2892
|
CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
|
2466
2893
|
}
|
@@ -2506,26 +2933,53 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
|
|
2506
2933
|
ASSERT(ToRegister(instr->value()).is(rax));
|
2507
2934
|
|
2508
2935
|
__ Move(rcx, instr->hydrogen()->name());
|
2509
|
-
Handle<Code> ic(
|
2936
|
+
Handle<Code> ic = info_->is_strict()
|
2937
|
+
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
2938
|
+
: isolate()->builtins()->StoreIC_Initialize();
|
2510
2939
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2511
2940
|
}
|
2512
2941
|
|
2513
2942
|
|
2514
|
-
void LCodeGen::
|
2943
|
+
void LCodeGen::DoStoreKeyedSpecializedArrayElement(
|
2944
|
+
LStoreKeyedSpecializedArrayElement* instr) {
|
2515
2945
|
Register external_pointer = ToRegister(instr->external_pointer());
|
2516
2946
|
Register key = ToRegister(instr->key());
|
2517
|
-
|
2518
|
-
|
2519
|
-
|
2520
|
-
|
2521
|
-
__
|
2522
|
-
|
2523
|
-
|
2524
|
-
|
2525
|
-
|
2947
|
+
ExternalArrayType array_type = instr->array_type();
|
2948
|
+
if (array_type == kExternalFloatArray) {
|
2949
|
+
XMMRegister value(ToDoubleRegister(instr->value()));
|
2950
|
+
__ cvtsd2ss(value, value);
|
2951
|
+
__ movss(Operand(external_pointer, key, times_4, 0), value);
|
2952
|
+
} else {
|
2953
|
+
Register value(ToRegister(instr->value()));
|
2954
|
+
switch (array_type) {
|
2955
|
+
case kExternalPixelArray:
|
2956
|
+
{ // Clamp the value to [0..255].
|
2957
|
+
NearLabel done;
|
2958
|
+
__ testl(value, Immediate(0xFFFFFF00));
|
2959
|
+
__ j(zero, &done);
|
2960
|
+
__ setcc(negative, value); // 1 if negative, 0 if positive.
|
2961
|
+
__ decb(value); // 0 if negative, 255 if positive.
|
2962
|
+
__ bind(&done);
|
2963
|
+
__ movb(Operand(external_pointer, key, times_1, 0), value);
|
2964
|
+
}
|
2965
|
+
break;
|
2966
|
+
case kExternalByteArray:
|
2967
|
+
case kExternalUnsignedByteArray:
|
2968
|
+
__ movb(Operand(external_pointer, key, times_1, 0), value);
|
2969
|
+
break;
|
2970
|
+
case kExternalShortArray:
|
2971
|
+
case kExternalUnsignedShortArray:
|
2972
|
+
__ movw(Operand(external_pointer, key, times_2, 0), value);
|
2973
|
+
break;
|
2974
|
+
case kExternalIntArray:
|
2975
|
+
case kExternalUnsignedIntArray:
|
2976
|
+
__ movl(Operand(external_pointer, key, times_4, 0), value);
|
2977
|
+
break;
|
2978
|
+
case kExternalFloatArray:
|
2979
|
+
UNREACHABLE();
|
2980
|
+
break;
|
2981
|
+
}
|
2526
2982
|
}
|
2527
|
-
|
2528
|
-
__ movb(Operand(external_pointer, key, times_1, 0), value);
|
2529
2983
|
}
|
2530
2984
|
|
2531
2985
|
|
@@ -2575,7 +3029,9 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
|
|
2575
3029
|
ASSERT(ToRegister(instr->key()).is(rcx));
|
2576
3030
|
ASSERT(ToRegister(instr->value()).is(rax));
|
2577
3031
|
|
2578
|
-
Handle<Code> ic(
|
3032
|
+
Handle<Code> ic = info_->is_strict()
|
3033
|
+
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
|
3034
|
+
: isolate()->builtins()->KeyedStoreIC_Initialize();
|
2579
3035
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2580
3036
|
}
|
2581
3037
|
|
@@ -2720,6 +3176,56 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
|
|
2720
3176
|
}
|
2721
3177
|
|
2722
3178
|
|
3179
|
+
void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
|
3180
|
+
class DeferredStringCharFromCode: public LDeferredCode {
|
3181
|
+
public:
|
3182
|
+
DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
|
3183
|
+
: LDeferredCode(codegen), instr_(instr) { }
|
3184
|
+
virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); }
|
3185
|
+
private:
|
3186
|
+
LStringCharFromCode* instr_;
|
3187
|
+
};
|
3188
|
+
|
3189
|
+
DeferredStringCharFromCode* deferred =
|
3190
|
+
new DeferredStringCharFromCode(this, instr);
|
3191
|
+
|
3192
|
+
ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
|
3193
|
+
Register char_code = ToRegister(instr->char_code());
|
3194
|
+
Register result = ToRegister(instr->result());
|
3195
|
+
ASSERT(!char_code.is(result));
|
3196
|
+
|
3197
|
+
__ cmpl(char_code, Immediate(String::kMaxAsciiCharCode));
|
3198
|
+
__ j(above, deferred->entry());
|
3199
|
+
__ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
|
3200
|
+
__ movq(result, FieldOperand(result,
|
3201
|
+
char_code, times_pointer_size,
|
3202
|
+
FixedArray::kHeaderSize));
|
3203
|
+
__ CompareRoot(result, Heap::kUndefinedValueRootIndex);
|
3204
|
+
__ j(equal, deferred->entry());
|
3205
|
+
__ bind(deferred->exit());
|
3206
|
+
}
|
3207
|
+
|
3208
|
+
|
3209
|
+
void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
|
3210
|
+
Register char_code = ToRegister(instr->char_code());
|
3211
|
+
Register result = ToRegister(instr->result());
|
3212
|
+
|
3213
|
+
// TODO(3095996): Get rid of this. For now, we need to make the
|
3214
|
+
// result register contain a valid pointer because it is already
|
3215
|
+
// contained in the register pointer map.
|
3216
|
+
__ Set(result, 0);
|
3217
|
+
|
3218
|
+
__ PushSafepointRegisters();
|
3219
|
+
__ Integer32ToSmi(char_code, char_code);
|
3220
|
+
__ push(char_code);
|
3221
|
+
__ CallRuntimeSaveDoubles(Runtime::kCharFromCode);
|
3222
|
+
RecordSafepointWithRegisters(
|
3223
|
+
instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex);
|
3224
|
+
__ StoreToSafepointRegisterSlot(result, rax);
|
3225
|
+
__ PopSafepointRegisters();
|
3226
|
+
}
|
3227
|
+
|
3228
|
+
|
2723
3229
|
void LCodeGen::DoStringLength(LStringLength* instr) {
|
2724
3230
|
Register string = ToRegister(instr->string());
|
2725
3231
|
Register result = ToRegister(instr->result());
|
@@ -2970,11 +3476,14 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
|
|
2970
3476
|
|
2971
3477
|
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
|
2972
3478
|
LOperand* input = instr->InputAt(0);
|
2973
|
-
ASSERT(input->IsRegister());
|
2974
3479
|
Condition cc = masm()->CheckSmi(ToRegister(input));
|
2975
|
-
|
2976
|
-
|
2977
|
-
|
3480
|
+
DeoptimizeIf(NegateCondition(cc), instr->environment());
|
3481
|
+
}
|
3482
|
+
|
3483
|
+
|
3484
|
+
void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
|
3485
|
+
LOperand* input = instr->InputAt(0);
|
3486
|
+
Condition cc = masm()->CheckSmi(ToRegister(input));
|
2978
3487
|
DeoptimizeIf(cc, instr->environment());
|
2979
3488
|
}
|
2980
3489
|
|
@@ -3029,9 +3538,9 @@ void LCodeGen::DoCheckMap(LCheckMap* instr) {
|
|
3029
3538
|
|
3030
3539
|
|
3031
3540
|
void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) {
|
3032
|
-
if (
|
3541
|
+
if (heap()->InNewSpace(*object)) {
|
3033
3542
|
Handle<JSGlobalPropertyCell> cell =
|
3034
|
-
|
3543
|
+
factory()->NewJSGlobalPropertyCell(object);
|
3035
3544
|
__ movq(result, cell, RelocInfo::GLOBAL_PROPERTY_CELL);
|
3036
3545
|
__ movq(result, Operand(result, 0));
|
3037
3546
|
} else {
|
@@ -3112,6 +3621,13 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
|
|
3112
3621
|
}
|
3113
3622
|
|
3114
3623
|
|
3624
|
+
void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
|
3625
|
+
ASSERT(ToRegister(instr->InputAt(0)).is(rax));
|
3626
|
+
__ push(rax);
|
3627
|
+
CallRuntime(Runtime::kToFastProperties, 1, instr);
|
3628
|
+
}
|
3629
|
+
|
3630
|
+
|
3115
3631
|
void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
|
3116
3632
|
NearLabel materialized;
|
3117
3633
|
// Registers will be used as follows:
|
@@ -3169,14 +3685,17 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
|
|
3169
3685
|
// space for nested functions that don't need literals cloning.
|
3170
3686
|
Handle<SharedFunctionInfo> shared_info = instr->shared_info();
|
3171
3687
|
bool pretenure = instr->hydrogen()->pretenure();
|
3172
|
-
if (shared_info->num_literals() == 0
|
3173
|
-
FastNewClosureStub stub
|
3688
|
+
if (!pretenure && shared_info->num_literals() == 0) {
|
3689
|
+
FastNewClosureStub stub(
|
3690
|
+
shared_info->strict_mode() ? kStrictMode : kNonStrictMode);
|
3174
3691
|
__ Push(shared_info);
|
3175
3692
|
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
3176
3693
|
} else {
|
3177
3694
|
__ push(rsi);
|
3178
3695
|
__ Push(shared_info);
|
3179
|
-
__
|
3696
|
+
__ PushRoot(pretenure ?
|
3697
|
+
Heap::kTrueValueRootIndex :
|
3698
|
+
Heap::kFalseValueRootIndex);
|
3180
3699
|
CallRuntime(Runtime::kNewClosure, 3, instr);
|
3181
3700
|
}
|
3182
3701
|
}
|
@@ -3257,28 +3776,28 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
|
|
3257
3776
|
Register input,
|
3258
3777
|
Handle<String> type_name) {
|
3259
3778
|
Condition final_branch_condition = no_condition;
|
3260
|
-
if (type_name->Equals(
|
3779
|
+
if (type_name->Equals(heap()->number_symbol())) {
|
3261
3780
|
__ JumpIfSmi(input, true_label);
|
3262
|
-
__
|
3263
|
-
|
3781
|
+
__ CompareRoot(FieldOperand(input, HeapObject::kMapOffset),
|
3782
|
+
Heap::kHeapNumberMapRootIndex);
|
3783
|
+
|
3264
3784
|
final_branch_condition = equal;
|
3265
3785
|
|
3266
|
-
} else if (type_name->Equals(
|
3786
|
+
} else if (type_name->Equals(heap()->string_symbol())) {
|
3267
3787
|
__ JumpIfSmi(input, false_label);
|
3268
|
-
__
|
3788
|
+
__ CmpObjectType(input, FIRST_NONSTRING_TYPE, input);
|
3789
|
+
__ j(above_equal, false_label);
|
3269
3790
|
__ testb(FieldOperand(input, Map::kBitFieldOffset),
|
3270
3791
|
Immediate(1 << Map::kIsUndetectable));
|
3271
|
-
|
3272
|
-
__ CmpInstanceType(input, FIRST_NONSTRING_TYPE);
|
3273
|
-
final_branch_condition = below;
|
3792
|
+
final_branch_condition = zero;
|
3274
3793
|
|
3275
|
-
} else if (type_name->Equals(
|
3794
|
+
} else if (type_name->Equals(heap()->boolean_symbol())) {
|
3276
3795
|
__ CompareRoot(input, Heap::kTrueValueRootIndex);
|
3277
3796
|
__ j(equal, true_label);
|
3278
3797
|
__ CompareRoot(input, Heap::kFalseValueRootIndex);
|
3279
3798
|
final_branch_condition = equal;
|
3280
3799
|
|
3281
|
-
} else if (type_name->Equals(
|
3800
|
+
} else if (type_name->Equals(heap()->undefined_symbol())) {
|
3282
3801
|
__ CompareRoot(input, Heap::kUndefinedValueRootIndex);
|
3283
3802
|
__ j(equal, true_label);
|
3284
3803
|
__ JumpIfSmi(input, false_label);
|
@@ -3288,24 +3807,23 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
|
|
3288
3807
|
Immediate(1 << Map::kIsUndetectable));
|
3289
3808
|
final_branch_condition = not_zero;
|
3290
3809
|
|
3291
|
-
} else if (type_name->Equals(
|
3810
|
+
} else if (type_name->Equals(heap()->function_symbol())) {
|
3292
3811
|
__ JumpIfSmi(input, false_label);
|
3293
3812
|
__ CmpObjectType(input, FIRST_FUNCTION_CLASS_TYPE, input);
|
3294
3813
|
final_branch_condition = above_equal;
|
3295
3814
|
|
3296
|
-
} else if (type_name->Equals(
|
3815
|
+
} else if (type_name->Equals(heap()->object_symbol())) {
|
3297
3816
|
__ JumpIfSmi(input, false_label);
|
3298
|
-
__
|
3817
|
+
__ CompareRoot(input, Heap::kNullValueRootIndex);
|
3299
3818
|
__ j(equal, true_label);
|
3819
|
+
__ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input);
|
3820
|
+
__ j(below, false_label);
|
3821
|
+
__ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
|
3822
|
+
__ j(above_equal, false_label);
|
3300
3823
|
// Check for undetectable objects => false.
|
3301
3824
|
__ testb(FieldOperand(input, Map::kBitFieldOffset),
|
3302
3825
|
Immediate(1 << Map::kIsUndetectable));
|
3303
|
-
|
3304
|
-
// Check for JS objects that are not RegExp or Function => true.
|
3305
|
-
__ CmpInstanceType(input, FIRST_JS_OBJECT_TYPE);
|
3306
|
-
__ j(below, false_label);
|
3307
|
-
__ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
|
3308
|
-
final_branch_condition = below_equal;
|
3826
|
+
final_branch_condition = zero;
|
3309
3827
|
|
3310
3828
|
} else {
|
3311
3829
|
final_branch_condition = never;
|
@@ -3352,15 +3870,15 @@ void LCodeGen::EmitIsConstructCall(Register temp) {
|
|
3352
3870
|
|
3353
3871
|
// Skip the arguments adaptor frame if it exists.
|
3354
3872
|
NearLabel check_frame_marker;
|
3355
|
-
__
|
3356
|
-
|
3873
|
+
__ Cmp(Operand(temp, StandardFrameConstants::kContextOffset),
|
3874
|
+
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
3357
3875
|
__ j(not_equal, &check_frame_marker);
|
3358
3876
|
__ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset));
|
3359
3877
|
|
3360
3878
|
// Check the marker in the calling frame.
|
3361
3879
|
__ bind(&check_frame_marker);
|
3362
|
-
__
|
3363
|
-
|
3880
|
+
__ Cmp(Operand(temp, StandardFrameConstants::kMarkerOffset),
|
3881
|
+
Smi::FromInt(StackFrame::CONSTRUCT));
|
3364
3882
|
}
|
3365
3883
|
|
3366
3884
|
|
@@ -3402,8 +3920,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
|
|
3402
3920
|
// builtin)
|
3403
3921
|
SafepointGenerator safepoint_generator(this,
|
3404
3922
|
pointers,
|
3405
|
-
env->deoptimization_index()
|
3406
|
-
true);
|
3923
|
+
env->deoptimization_index());
|
3407
3924
|
__ Push(Smi::FromInt(strict_mode_flag()));
|
3408
3925
|
__ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
|
3409
3926
|
}
|