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
@@ -31,6 +31,7 @@
|
|
31
31
|
|
32
32
|
#include "ia32/lithium-codegen-ia32.h"
|
33
33
|
#include "code-stubs.h"
|
34
|
+
#include "deoptimizer.h"
|
34
35
|
#include "stub-cache.h"
|
35
36
|
|
36
37
|
namespace v8 {
|
@@ -43,20 +44,13 @@ class SafepointGenerator : public PostCallGenerator {
|
|
43
44
|
public:
|
44
45
|
SafepointGenerator(LCodeGen* codegen,
|
45
46
|
LPointerMap* pointers,
|
46
|
-
int deoptimization_index
|
47
|
-
bool ensure_reloc_space = false)
|
47
|
+
int deoptimization_index)
|
48
48
|
: codegen_(codegen),
|
49
49
|
pointers_(pointers),
|
50
|
-
deoptimization_index_(deoptimization_index)
|
51
|
-
ensure_reloc_space_(ensure_reloc_space) { }
|
50
|
+
deoptimization_index_(deoptimization_index) {}
|
52
51
|
virtual ~SafepointGenerator() { }
|
53
52
|
|
54
53
|
virtual void Generate() {
|
55
|
-
// Ensure that we have enough space in the reloc info to patch
|
56
|
-
// this with calls when doing deoptimization.
|
57
|
-
if (ensure_reloc_space_) {
|
58
|
-
codegen_->EnsureRelocSpaceForDeoptimization();
|
59
|
-
}
|
60
54
|
codegen_->RecordSafepoint(pointers_, deoptimization_index_);
|
61
55
|
}
|
62
56
|
|
@@ -64,7 +58,6 @@ class SafepointGenerator : public PostCallGenerator {
|
|
64
58
|
LCodeGen* codegen_;
|
65
59
|
LPointerMap* pointers_;
|
66
60
|
int deoptimization_index_;
|
67
|
-
bool ensure_reloc_space_;
|
68
61
|
};
|
69
62
|
|
70
63
|
|
@@ -78,7 +71,6 @@ bool LCodeGen::GenerateCode() {
|
|
78
71
|
return GeneratePrologue() &&
|
79
72
|
GenerateBody() &&
|
80
73
|
GenerateDeferredCode() &&
|
81
|
-
GenerateRelocPadding() &&
|
82
74
|
GenerateSafepointTable();
|
83
75
|
}
|
84
76
|
|
@@ -88,13 +80,14 @@ void LCodeGen::FinishCode(Handle<Code> code) {
|
|
88
80
|
code->set_stack_slots(StackSlotCount());
|
89
81
|
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
|
90
82
|
PopulateDeoptimizationData(code);
|
83
|
+
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
|
91
84
|
}
|
92
85
|
|
93
86
|
|
94
87
|
void LCodeGen::Abort(const char* format, ...) {
|
95
88
|
if (FLAG_trace_bailout) {
|
96
|
-
SmartPointer<char>
|
97
|
-
PrintF("Aborting LCodeGen in @\"%s\": ", *
|
89
|
+
SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString());
|
90
|
+
PrintF("Aborting LCodeGen in @\"%s\": ", *name);
|
98
91
|
va_list arguments;
|
99
92
|
va_start(arguments, format);
|
100
93
|
OS::VPrint(format, arguments);
|
@@ -123,16 +116,6 @@ void LCodeGen::Comment(const char* format, ...) {
|
|
123
116
|
}
|
124
117
|
|
125
118
|
|
126
|
-
bool LCodeGen::GenerateRelocPadding() {
|
127
|
-
int reloc_size = masm()->relocation_writer_size();
|
128
|
-
while (reloc_size < deoptimization_reloc_size.min_size) {
|
129
|
-
__ RecordComment(RelocInfo::kFillerCommentString, true);
|
130
|
-
reloc_size += RelocInfo::kRelocCommentSize;
|
131
|
-
}
|
132
|
-
return !is_aborted();
|
133
|
-
}
|
134
|
-
|
135
|
-
|
136
119
|
bool LCodeGen::GeneratePrologue() {
|
137
120
|
ASSERT(is_generating());
|
138
121
|
|
@@ -385,22 +368,6 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
|
|
385
368
|
}
|
386
369
|
|
387
370
|
|
388
|
-
void LCodeGen::EnsureRelocSpaceForDeoptimization() {
|
389
|
-
// Since we patch the reloc info with RUNTIME_ENTRY calls every patch
|
390
|
-
// site will take up 2 bytes + any pc-jumps.
|
391
|
-
// We are conservative and always reserver 6 bytes in case where a
|
392
|
-
// simple pc-jump is not enough.
|
393
|
-
uint32_t pc_delta =
|
394
|
-
masm()->pc_offset() - deoptimization_reloc_size.last_pc_offset;
|
395
|
-
if (is_uintn(pc_delta, 6)) {
|
396
|
-
deoptimization_reloc_size.min_size += 2;
|
397
|
-
} else {
|
398
|
-
deoptimization_reloc_size.min_size += 6;
|
399
|
-
}
|
400
|
-
deoptimization_reloc_size.last_pc_offset = masm()->pc_offset();
|
401
|
-
}
|
402
|
-
|
403
|
-
|
404
371
|
void LCodeGen::AddToTranslation(Translation* translation,
|
405
372
|
LOperand* op,
|
406
373
|
bool is_tagged) {
|
@@ -454,7 +421,6 @@ void LCodeGen::CallCode(Handle<Code> code,
|
|
454
421
|
}
|
455
422
|
__ call(code, mode);
|
456
423
|
|
457
|
-
EnsureRelocSpaceForDeoptimization();
|
458
424
|
RegisterLazyDeoptimization(instr);
|
459
425
|
|
460
426
|
// Signal that we don't inline smi code before these stubs in the
|
@@ -466,7 +432,7 @@ void LCodeGen::CallCode(Handle<Code> code,
|
|
466
432
|
}
|
467
433
|
|
468
434
|
|
469
|
-
void LCodeGen::CallRuntime(Runtime::Function* fun,
|
435
|
+
void LCodeGen::CallRuntime(const Runtime::Function* fun,
|
470
436
|
int argc,
|
471
437
|
LInstruction* instr,
|
472
438
|
bool adjusted) {
|
@@ -479,6 +445,7 @@ void LCodeGen::CallRuntime(Runtime::Function* fun,
|
|
479
445
|
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
480
446
|
}
|
481
447
|
__ CallRuntime(fun, argc);
|
448
|
+
|
482
449
|
RegisterLazyDeoptimization(instr);
|
483
450
|
}
|
484
451
|
|
@@ -586,13 +553,14 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
|
|
586
553
|
if (length == 0) return;
|
587
554
|
ASSERT(FLAG_deopt);
|
588
555
|
Handle<DeoptimizationInputData> data =
|
589
|
-
|
556
|
+
factory()->NewDeoptimizationInputData(length, TENURED);
|
590
557
|
|
591
|
-
|
558
|
+
Handle<ByteArray> translations = translations_.CreateByteArray();
|
559
|
+
data->SetTranslationByteArray(*translations);
|
592
560
|
data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
|
593
561
|
|
594
562
|
Handle<FixedArray> literals =
|
595
|
-
|
563
|
+
factory()->NewFixedArray(deoptimization_literals_.length(), TENURED);
|
596
564
|
for (int i = 0; i < deoptimization_literals_.length(); i++) {
|
597
565
|
literals->set(i, *deoptimization_literals_[i]);
|
598
566
|
}
|
@@ -742,16 +710,6 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
|
|
742
710
|
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
743
711
|
break;
|
744
712
|
}
|
745
|
-
case CodeStub::StringCharAt: {
|
746
|
-
StringCharAtStub stub;
|
747
|
-
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
748
|
-
break;
|
749
|
-
}
|
750
|
-
case CodeStub::MathPow: {
|
751
|
-
MathPowStub stub;
|
752
|
-
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
753
|
-
break;
|
754
|
-
}
|
755
713
|
case CodeStub::NumberToString: {
|
756
714
|
NumberToStringStub stub;
|
757
715
|
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
@@ -785,41 +743,64 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
|
|
785
743
|
|
786
744
|
|
787
745
|
void LCodeGen::DoModI(LModI* instr) {
|
788
|
-
|
789
|
-
|
790
|
-
ASSERT(ToRegister(instr->InputAt(0)).is(eax));
|
791
|
-
ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
|
792
|
-
ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
|
746
|
+
if (instr->hydrogen()->HasPowerOf2Divisor()) {
|
747
|
+
Register dividend = ToRegister(instr->InputAt(0));
|
793
748
|
|
794
|
-
|
749
|
+
int32_t divisor =
|
750
|
+
HConstant::cast(instr->hydrogen()->right())->Integer32Value();
|
795
751
|
|
796
|
-
|
797
|
-
if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
|
798
|
-
__ test(right_reg, ToOperand(right));
|
799
|
-
DeoptimizeIf(zero, instr->environment());
|
800
|
-
}
|
752
|
+
if (divisor < 0) divisor = -divisor;
|
801
753
|
|
802
|
-
|
803
|
-
|
754
|
+
NearLabel positive_dividend, done;
|
755
|
+
__ test(dividend, Operand(dividend));
|
756
|
+
__ j(not_sign, &positive_dividend);
|
757
|
+
__ neg(dividend);
|
758
|
+
__ and_(dividend, divisor - 1);
|
759
|
+
__ neg(dividend);
|
760
|
+
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
761
|
+
__ j(not_zero, &done);
|
762
|
+
DeoptimizeIf(no_condition, instr->environment());
|
763
|
+
}
|
764
|
+
__ bind(&positive_dividend);
|
765
|
+
__ and_(dividend, divisor - 1);
|
766
|
+
__ bind(&done);
|
767
|
+
} else {
|
768
|
+
LOperand* right = instr->InputAt(1);
|
769
|
+
ASSERT(ToRegister(instr->InputAt(0)).is(eax));
|
770
|
+
ASSERT(ToRegister(instr->result()).is(edx));
|
804
771
|
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
NearLabel done;
|
809
|
-
__ test(eax, Operand(eax));
|
810
|
-
__ j(not_sign, &positive_left);
|
811
|
-
__ idiv(right_reg);
|
772
|
+
Register right_reg = ToRegister(right);
|
773
|
+
ASSERT(!right_reg.is(eax));
|
774
|
+
ASSERT(!right_reg.is(edx));
|
812
775
|
|
813
|
-
//
|
814
|
-
|
815
|
-
|
776
|
+
// Check for x % 0.
|
777
|
+
if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
|
778
|
+
__ test(right_reg, ToOperand(right));
|
779
|
+
DeoptimizeIf(zero, instr->environment());
|
780
|
+
}
|
816
781
|
|
817
|
-
|
818
|
-
__
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
782
|
+
// Sign extend to edx.
|
783
|
+
__ cdq();
|
784
|
+
|
785
|
+
// Check for (0 % -x) that will produce negative zero.
|
786
|
+
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
787
|
+
NearLabel positive_left;
|
788
|
+
NearLabel done;
|
789
|
+
__ test(eax, Operand(eax));
|
790
|
+
__ j(not_sign, &positive_left);
|
791
|
+
__ idiv(right_reg);
|
792
|
+
|
793
|
+
// Test the remainder for 0, because then the result would be -0.
|
794
|
+
__ test(edx, Operand(edx));
|
795
|
+
__ j(not_zero, &done);
|
796
|
+
|
797
|
+
DeoptimizeIf(no_condition, instr->environment());
|
798
|
+
__ bind(&positive_left);
|
799
|
+
__ idiv(right_reg);
|
800
|
+
__ bind(&done);
|
801
|
+
} else {
|
802
|
+
__ idiv(right_reg);
|
803
|
+
}
|
823
804
|
}
|
824
805
|
}
|
825
806
|
|
@@ -879,7 +860,49 @@ void LCodeGen::DoMulI(LMulI* instr) {
|
|
879
860
|
}
|
880
861
|
|
881
862
|
if (right->IsConstantOperand()) {
|
882
|
-
|
863
|
+
// Try strength reductions on the multiplication.
|
864
|
+
// All replacement instructions are at most as long as the imul
|
865
|
+
// and have better latency.
|
866
|
+
int constant = ToInteger32(LConstantOperand::cast(right));
|
867
|
+
if (constant == -1) {
|
868
|
+
__ neg(left);
|
869
|
+
} else if (constant == 0) {
|
870
|
+
__ xor_(left, Operand(left));
|
871
|
+
} else if (constant == 2) {
|
872
|
+
__ add(left, Operand(left));
|
873
|
+
} else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
|
874
|
+
// If we know that the multiplication can't overflow, it's safe to
|
875
|
+
// use instructions that don't set the overflow flag for the
|
876
|
+
// multiplication.
|
877
|
+
switch (constant) {
|
878
|
+
case 1:
|
879
|
+
// Do nothing.
|
880
|
+
break;
|
881
|
+
case 3:
|
882
|
+
__ lea(left, Operand(left, left, times_2, 0));
|
883
|
+
break;
|
884
|
+
case 4:
|
885
|
+
__ shl(left, 2);
|
886
|
+
break;
|
887
|
+
case 5:
|
888
|
+
__ lea(left, Operand(left, left, times_4, 0));
|
889
|
+
break;
|
890
|
+
case 8:
|
891
|
+
__ shl(left, 3);
|
892
|
+
break;
|
893
|
+
case 9:
|
894
|
+
__ lea(left, Operand(left, left, times_8, 0));
|
895
|
+
break;
|
896
|
+
case 16:
|
897
|
+
__ shl(left, 4);
|
898
|
+
break;
|
899
|
+
default:
|
900
|
+
__ imul(left, left, constant);
|
901
|
+
break;
|
902
|
+
}
|
903
|
+
} else {
|
904
|
+
__ imul(left, left, constant);
|
905
|
+
}
|
883
906
|
} else {
|
884
907
|
__ imul(left, ToOperand(right));
|
885
908
|
}
|
@@ -1085,10 +1108,10 @@ void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
|
|
1085
1108
|
}
|
1086
1109
|
|
1087
1110
|
|
1088
|
-
void LCodeGen::
|
1111
|
+
void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) {
|
1089
1112
|
Register result = ToRegister(instr->result());
|
1090
1113
|
Register array = ToRegister(instr->InputAt(0));
|
1091
|
-
__ mov(result, FieldOperand(array,
|
1114
|
+
__ mov(result, FieldOperand(array, ExternalArray::kLengthOffset));
|
1092
1115
|
}
|
1093
1116
|
|
1094
1117
|
|
@@ -1147,35 +1170,38 @@ void LCodeGen::DoAddI(LAddI* instr) {
|
|
1147
1170
|
|
1148
1171
|
|
1149
1172
|
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
|
1150
|
-
|
1151
|
-
|
1173
|
+
XMMRegister left = ToDoubleRegister(instr->InputAt(0));
|
1174
|
+
XMMRegister right = ToDoubleRegister(instr->InputAt(1));
|
1175
|
+
XMMRegister result = ToDoubleRegister(instr->result());
|
1152
1176
|
// Modulo uses a fixed result register.
|
1153
|
-
ASSERT(instr->op() == Token::MOD || left
|
1177
|
+
ASSERT(instr->op() == Token::MOD || left.is(result));
|
1154
1178
|
switch (instr->op()) {
|
1155
1179
|
case Token::ADD:
|
1156
|
-
__ addsd(
|
1180
|
+
__ addsd(left, right);
|
1157
1181
|
break;
|
1158
1182
|
case Token::SUB:
|
1159
|
-
__ subsd(
|
1183
|
+
__ subsd(left, right);
|
1160
1184
|
break;
|
1161
1185
|
case Token::MUL:
|
1162
|
-
__ mulsd(
|
1186
|
+
__ mulsd(left, right);
|
1163
1187
|
break;
|
1164
1188
|
case Token::DIV:
|
1165
|
-
__ divsd(
|
1189
|
+
__ divsd(left, right);
|
1166
1190
|
break;
|
1167
1191
|
case Token::MOD: {
|
1168
1192
|
// Pass two doubles as arguments on the stack.
|
1169
1193
|
__ PrepareCallCFunction(4, eax);
|
1170
|
-
__ movdbl(Operand(esp, 0 * kDoubleSize),
|
1171
|
-
__ movdbl(Operand(esp, 1 * kDoubleSize),
|
1172
|
-
__ CallCFunction(
|
1194
|
+
__ movdbl(Operand(esp, 0 * kDoubleSize), left);
|
1195
|
+
__ movdbl(Operand(esp, 1 * kDoubleSize), right);
|
1196
|
+
__ CallCFunction(
|
1197
|
+
ExternalReference::double_fp_operation(Token::MOD, isolate()),
|
1198
|
+
4);
|
1173
1199
|
|
1174
1200
|
// Return value is in st(0) on ia32.
|
1175
1201
|
// Store it into the (fixed) result register.
|
1176
1202
|
__ sub(Operand(esp), Immediate(kDoubleSize));
|
1177
1203
|
__ fstp_d(Operand(esp, 0));
|
1178
|
-
__ movdbl(
|
1204
|
+
__ movdbl(result, Operand(esp, 0));
|
1179
1205
|
__ add(Operand(esp), Immediate(kDoubleSize));
|
1180
1206
|
break;
|
1181
1207
|
}
|
@@ -1241,17 +1267,17 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
|
1241
1267
|
ASSERT(r.IsTagged());
|
1242
1268
|
Register reg = ToRegister(instr->InputAt(0));
|
1243
1269
|
if (instr->hydrogen()->type().IsBoolean()) {
|
1244
|
-
__ cmp(reg,
|
1270
|
+
__ cmp(reg, factory()->true_value());
|
1245
1271
|
EmitBranch(true_block, false_block, equal);
|
1246
1272
|
} else {
|
1247
1273
|
Label* true_label = chunk_->GetAssemblyLabel(true_block);
|
1248
1274
|
Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
1249
1275
|
|
1250
|
-
__ cmp(reg,
|
1276
|
+
__ cmp(reg, factory()->undefined_value());
|
1251
1277
|
__ j(equal, false_label);
|
1252
|
-
__ cmp(reg,
|
1278
|
+
__ cmp(reg, factory()->true_value());
|
1253
1279
|
__ j(equal, true_label);
|
1254
|
-
__ cmp(reg,
|
1280
|
+
__ cmp(reg, factory()->false_value());
|
1255
1281
|
__ j(equal, false_label);
|
1256
1282
|
__ test(reg, Operand(reg));
|
1257
1283
|
__ j(equal, false_label);
|
@@ -1261,7 +1287,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
|
|
1261
1287
|
// Test for double values. Zero is false.
|
1262
1288
|
NearLabel call_stub;
|
1263
1289
|
__ cmp(FieldOperand(reg, HeapObject::kMapOffset),
|
1264
|
-
|
1290
|
+
factory()->heap_number_map());
|
1265
1291
|
__ j(not_equal, &call_stub);
|
1266
1292
|
__ fldz();
|
1267
1293
|
__ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
|
@@ -1291,7 +1317,7 @@ void LCodeGen::EmitGoto(int block, LDeferredCode* deferred_stack_check) {
|
|
1291
1317
|
// Perform stack overflow check if this goto needs it before jumping.
|
1292
1318
|
if (deferred_stack_check != NULL) {
|
1293
1319
|
ExternalReference stack_limit =
|
1294
|
-
ExternalReference::address_of_stack_limit();
|
1320
|
+
ExternalReference::address_of_stack_limit(isolate());
|
1295
1321
|
__ cmp(esp, Operand::StaticVariable(stack_limit));
|
1296
1322
|
__ j(above_equal, chunk_->GetAssemblyLabel(block));
|
1297
1323
|
__ jmp(deferred_stack_check->entry());
|
@@ -1384,11 +1410,11 @@ void LCodeGen::DoCmpID(LCmpID* instr) {
|
|
1384
1410
|
|
1385
1411
|
NearLabel done;
|
1386
1412
|
Condition cc = TokenToCondition(instr->op(), instr->is_double());
|
1387
|
-
__ mov(ToRegister(result),
|
1413
|
+
__ mov(ToRegister(result), factory()->true_value());
|
1388
1414
|
__ j(cc, &done);
|
1389
1415
|
|
1390
1416
|
__ bind(&unordered);
|
1391
|
-
__ mov(ToRegister(result),
|
1417
|
+
__ mov(ToRegister(result), factory()->false_value());
|
1392
1418
|
__ bind(&done);
|
1393
1419
|
}
|
1394
1420
|
|
@@ -1419,10 +1445,10 @@ void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
|
|
1419
1445
|
Register result = ToRegister(instr->result());
|
1420
1446
|
|
1421
1447
|
__ cmp(left, Operand(right));
|
1422
|
-
__ mov(result,
|
1448
|
+
__ mov(result, factory()->true_value());
|
1423
1449
|
NearLabel done;
|
1424
1450
|
__ j(equal, &done);
|
1425
|
-
__ mov(result,
|
1451
|
+
__ mov(result, factory()->false_value());
|
1426
1452
|
__ bind(&done);
|
1427
1453
|
}
|
1428
1454
|
|
@@ -1445,17 +1471,17 @@ void LCodeGen::DoIsNull(LIsNull* instr) {
|
|
1445
1471
|
// TODO(fsc): If the expression is known to be a smi, then it's
|
1446
1472
|
// definitely not null. Materialize false.
|
1447
1473
|
|
1448
|
-
__ cmp(reg,
|
1474
|
+
__ cmp(reg, factory()->null_value());
|
1449
1475
|
if (instr->is_strict()) {
|
1450
|
-
__ mov(result,
|
1476
|
+
__ mov(result, factory()->true_value());
|
1451
1477
|
NearLabel done;
|
1452
1478
|
__ j(equal, &done);
|
1453
|
-
__ mov(result,
|
1479
|
+
__ mov(result, factory()->false_value());
|
1454
1480
|
__ bind(&done);
|
1455
1481
|
} else {
|
1456
1482
|
NearLabel true_value, false_value, done;
|
1457
1483
|
__ j(equal, &true_value);
|
1458
|
-
__ cmp(reg,
|
1484
|
+
__ cmp(reg, factory()->undefined_value());
|
1459
1485
|
__ j(equal, &true_value);
|
1460
1486
|
__ test(reg, Immediate(kSmiTagMask));
|
1461
1487
|
__ j(zero, &false_value);
|
@@ -1467,10 +1493,10 @@ void LCodeGen::DoIsNull(LIsNull* instr) {
|
|
1467
1493
|
__ test(scratch, Immediate(1 << Map::kIsUndetectable));
|
1468
1494
|
__ j(not_zero, &true_value);
|
1469
1495
|
__ bind(&false_value);
|
1470
|
-
__ mov(result,
|
1496
|
+
__ mov(result, factory()->false_value());
|
1471
1497
|
__ jmp(&done);
|
1472
1498
|
__ bind(&true_value);
|
1473
|
-
__ mov(result,
|
1499
|
+
__ mov(result, factory()->true_value());
|
1474
1500
|
__ bind(&done);
|
1475
1501
|
}
|
1476
1502
|
}
|
@@ -1485,14 +1511,14 @@ void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
|
|
1485
1511
|
int true_block = chunk_->LookupDestination(instr->true_block_id());
|
1486
1512
|
int false_block = chunk_->LookupDestination(instr->false_block_id());
|
1487
1513
|
|
1488
|
-
__ cmp(reg,
|
1514
|
+
__ cmp(reg, factory()->null_value());
|
1489
1515
|
if (instr->is_strict()) {
|
1490
1516
|
EmitBranch(true_block, false_block, equal);
|
1491
1517
|
} else {
|
1492
1518
|
Label* true_label = chunk_->GetAssemblyLabel(true_block);
|
1493
1519
|
Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
1494
1520
|
__ j(equal, true_label);
|
1495
|
-
__ cmp(reg,
|
1521
|
+
__ cmp(reg, factory()->undefined_value());
|
1496
1522
|
__ j(equal, true_label);
|
1497
1523
|
__ test(reg, Immediate(kSmiTagMask));
|
1498
1524
|
__ j(zero, false_label);
|
@@ -1519,7 +1545,7 @@ Condition LCodeGen::EmitIsObject(Register input,
|
|
1519
1545
|
__ test(input, Immediate(kSmiTagMask));
|
1520
1546
|
__ j(equal, is_not_object);
|
1521
1547
|
|
1522
|
-
__ cmp(input,
|
1548
|
+
__ cmp(input, isolate()->factory()->null_value());
|
1523
1549
|
__ j(equal, is_object);
|
1524
1550
|
|
1525
1551
|
__ mov(temp1, FieldOperand(input, HeapObject::kMapOffset));
|
@@ -1546,11 +1572,11 @@ void LCodeGen::DoIsObject(LIsObject* instr) {
|
|
1546
1572
|
__ j(true_cond, &is_true);
|
1547
1573
|
|
1548
1574
|
__ bind(&is_false);
|
1549
|
-
__ mov(result,
|
1575
|
+
__ mov(result, factory()->false_value());
|
1550
1576
|
__ jmp(&done);
|
1551
1577
|
|
1552
1578
|
__ bind(&is_true);
|
1553
|
-
__ mov(result,
|
1579
|
+
__ mov(result, factory()->true_value());
|
1554
1580
|
|
1555
1581
|
__ bind(&done);
|
1556
1582
|
}
|
@@ -1578,10 +1604,10 @@ void LCodeGen::DoIsSmi(LIsSmi* instr) {
|
|
1578
1604
|
|
1579
1605
|
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
|
1580
1606
|
__ test(input, Immediate(kSmiTagMask));
|
1581
|
-
__ mov(result,
|
1607
|
+
__ mov(result, factory()->true_value());
|
1582
1608
|
NearLabel done;
|
1583
1609
|
__ j(zero, &done);
|
1584
|
-
__ mov(result,
|
1610
|
+
__ mov(result, factory()->false_value());
|
1585
1611
|
__ bind(&done);
|
1586
1612
|
}
|
1587
1613
|
|
@@ -1627,10 +1653,10 @@ void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
|
|
1627
1653
|
__ j(zero, &is_false);
|
1628
1654
|
__ CmpObjectType(input, TestType(instr->hydrogen()), result);
|
1629
1655
|
__ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
|
1630
|
-
__ mov(result,
|
1656
|
+
__ mov(result, factory()->true_value());
|
1631
1657
|
__ jmp(&done);
|
1632
1658
|
__ bind(&is_false);
|
1633
|
-
__ mov(result,
|
1659
|
+
__ mov(result, factory()->false_value());
|
1634
1660
|
__ bind(&done);
|
1635
1661
|
}
|
1636
1662
|
|
@@ -1652,17 +1678,30 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
|
|
1652
1678
|
}
|
1653
1679
|
|
1654
1680
|
|
1681
|
+
void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
|
1682
|
+
Register input = ToRegister(instr->InputAt(0));
|
1683
|
+
Register result = ToRegister(instr->result());
|
1684
|
+
|
1685
|
+
if (FLAG_debug_code) {
|
1686
|
+
__ AbortIfNotString(input);
|
1687
|
+
}
|
1688
|
+
|
1689
|
+
__ mov(result, FieldOperand(input, String::kHashFieldOffset));
|
1690
|
+
__ IndexFromHash(result, result);
|
1691
|
+
}
|
1692
|
+
|
1693
|
+
|
1655
1694
|
void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
|
1656
1695
|
Register input = ToRegister(instr->InputAt(0));
|
1657
1696
|
Register result = ToRegister(instr->result());
|
1658
1697
|
|
1659
1698
|
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
|
1660
|
-
__ mov(result,
|
1699
|
+
__ mov(result, factory()->true_value());
|
1661
1700
|
__ test(FieldOperand(input, String::kHashFieldOffset),
|
1662
1701
|
Immediate(String::kContainsCachedArrayIndexMask));
|
1663
1702
|
NearLabel done;
|
1664
|
-
__ j(
|
1665
|
-
__ mov(result,
|
1703
|
+
__ j(zero, &done);
|
1704
|
+
__ mov(result, factory()->false_value());
|
1666
1705
|
__ bind(&done);
|
1667
1706
|
}
|
1668
1707
|
|
@@ -1676,7 +1715,7 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
|
|
1676
1715
|
|
1677
1716
|
__ test(FieldOperand(input, String::kHashFieldOffset),
|
1678
1717
|
Immediate(String::kContainsCachedArrayIndexMask));
|
1679
|
-
EmitBranch(true_block, false_block,
|
1718
|
+
EmitBranch(true_block, false_block, equal);
|
1680
1719
|
}
|
1681
1720
|
|
1682
1721
|
|
@@ -1751,11 +1790,11 @@ void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
|
|
1751
1790
|
__ j(not_equal, &is_false);
|
1752
1791
|
|
1753
1792
|
__ bind(&is_true);
|
1754
|
-
__ mov(result,
|
1793
|
+
__ mov(result, factory()->true_value());
|
1755
1794
|
__ jmp(&done);
|
1756
1795
|
|
1757
1796
|
__ bind(&is_false);
|
1758
|
-
__ mov(result,
|
1797
|
+
__ mov(result, factory()->false_value());
|
1759
1798
|
__ bind(&done);
|
1760
1799
|
}
|
1761
1800
|
|
@@ -1803,10 +1842,10 @@ void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
|
|
1803
1842
|
NearLabel true_value, done;
|
1804
1843
|
__ test(eax, Operand(eax));
|
1805
1844
|
__ j(zero, &true_value);
|
1806
|
-
__ mov(ToRegister(instr->result()),
|
1845
|
+
__ mov(ToRegister(instr->result()), factory()->false_value());
|
1807
1846
|
__ jmp(&done);
|
1808
1847
|
__ bind(&true_value);
|
1809
|
-
__ mov(ToRegister(instr->result()),
|
1848
|
+
__ mov(ToRegister(instr->result()), factory()->true_value());
|
1810
1849
|
__ bind(&done);
|
1811
1850
|
}
|
1812
1851
|
|
@@ -1858,16 +1897,16 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
|
|
1858
1897
|
Register map = ToRegister(instr->TempAt(0));
|
1859
1898
|
__ mov(map, FieldOperand(object, HeapObject::kMapOffset));
|
1860
1899
|
__ bind(deferred->map_check()); // Label for calculating code patching.
|
1861
|
-
__ cmp(map,
|
1900
|
+
__ cmp(map, factory()->the_hole_value()); // Patched to cached map.
|
1862
1901
|
__ j(not_equal, &cache_miss, not_taken);
|
1863
|
-
__ mov(eax,
|
1902
|
+
__ mov(eax, factory()->the_hole_value()); // Patched to either true or false.
|
1864
1903
|
__ jmp(&done);
|
1865
1904
|
|
1866
1905
|
// The inlined call site cache did not match. Check for null and string
|
1867
1906
|
// before calling the deferred code.
|
1868
1907
|
__ bind(&cache_miss);
|
1869
1908
|
// Null is not an instance of anything.
|
1870
|
-
__ cmp(object,
|
1909
|
+
__ cmp(object, factory()->null_value());
|
1871
1910
|
__ j(equal, &false_result);
|
1872
1911
|
|
1873
1912
|
// String values are not instances of anything.
|
@@ -1878,7 +1917,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
|
|
1878
1917
|
__ jmp(deferred->entry());
|
1879
1918
|
|
1880
1919
|
__ bind(&false_result);
|
1881
|
-
__ mov(ToRegister(instr->result()),
|
1920
|
+
__ mov(ToRegister(instr->result()), factory()->false_value());
|
1882
1921
|
|
1883
1922
|
// Here result has either true or false. Deferred code also produces true or
|
1884
1923
|
// false object.
|
@@ -1908,16 +1947,9 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
|
|
1908
1947
|
__ mov(InstanceofStub::right(), Immediate(instr->function()));
|
1909
1948
|
static const int kAdditionalDelta = 16;
|
1910
1949
|
int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
|
1911
|
-
Label before_push_delta;
|
1912
|
-
__ bind(&before_push_delta);
|
1913
1950
|
__ mov(temp, Immediate(delta));
|
1914
1951
|
__ StoreToSafepointRegisterSlot(temp, temp);
|
1915
|
-
|
1916
|
-
__ call(stub.GetCode(), RelocInfo::CODE_TARGET);
|
1917
|
-
ASSERT_EQ(kAdditionalDelta,
|
1918
|
-
masm_->SizeOfCodeGeneratedSince(&before_push_delta));
|
1919
|
-
RecordSafepointWithRegisters(
|
1920
|
-
instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
|
1952
|
+
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false);
|
1921
1953
|
// Put the result value into the eax slot and restore all registers.
|
1922
1954
|
__ StoreToSafepointRegisterSlot(eax, eax);
|
1923
1955
|
__ PopSafepointRegisters();
|
@@ -1957,10 +1989,10 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
|
|
1957
1989
|
NearLabel true_value, done;
|
1958
1990
|
__ test(eax, Operand(eax));
|
1959
1991
|
__ j(condition, &true_value);
|
1960
|
-
__ mov(ToRegister(instr->result()),
|
1992
|
+
__ mov(ToRegister(instr->result()), factory()->false_value());
|
1961
1993
|
__ jmp(&done);
|
1962
1994
|
__ bind(&true_value);
|
1963
|
-
__ mov(ToRegister(instr->result()),
|
1995
|
+
__ mov(ToRegister(instr->result()), factory()->true_value());
|
1964
1996
|
__ bind(&done);
|
1965
1997
|
}
|
1966
1998
|
|
@@ -2000,16 +2032,29 @@ void LCodeGen::DoReturn(LReturn* instr) {
|
|
2000
2032
|
}
|
2001
2033
|
|
2002
2034
|
|
2003
|
-
void LCodeGen::
|
2035
|
+
void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
|
2004
2036
|
Register result = ToRegister(instr->result());
|
2005
2037
|
__ mov(result, Operand::Cell(instr->hydrogen()->cell()));
|
2006
2038
|
if (instr->hydrogen()->check_hole_value()) {
|
2007
|
-
__ cmp(result,
|
2039
|
+
__ cmp(result, factory()->the_hole_value());
|
2008
2040
|
DeoptimizeIf(equal, instr->environment());
|
2009
2041
|
}
|
2010
2042
|
}
|
2011
2043
|
|
2012
2044
|
|
2045
|
+
void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
|
2046
|
+
ASSERT(ToRegister(instr->context()).is(esi));
|
2047
|
+
ASSERT(ToRegister(instr->global_object()).is(eax));
|
2048
|
+
ASSERT(ToRegister(instr->result()).is(eax));
|
2049
|
+
|
2050
|
+
__ mov(ecx, instr->name());
|
2051
|
+
RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET :
|
2052
|
+
RelocInfo::CODE_TARGET_CONTEXT;
|
2053
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
2054
|
+
CallCode(ic, mode, instr);
|
2055
|
+
}
|
2056
|
+
|
2057
|
+
|
2013
2058
|
void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
|
2014
2059
|
Register value = ToRegister(instr->InputAt(0));
|
2015
2060
|
Operand cell_operand = Operand::Cell(instr->hydrogen()->cell());
|
@@ -2019,7 +2064,7 @@ void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
|
|
2019
2064
|
// to update the property details in the property dictionary to mark
|
2020
2065
|
// it as no longer deleted. We deoptimize in that case.
|
2021
2066
|
if (instr->hydrogen()->check_hole_value()) {
|
2022
|
-
__ cmp(cell_operand,
|
2067
|
+
__ cmp(cell_operand, factory()->the_hole_value());
|
2023
2068
|
DeoptimizeIf(equal, instr->environment());
|
2024
2069
|
}
|
2025
2070
|
|
@@ -2048,7 +2093,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
|
|
2048
2093
|
|
2049
2094
|
|
2050
2095
|
void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
|
2051
|
-
Register object = ToRegister(instr->
|
2096
|
+
Register object = ToRegister(instr->object());
|
2052
2097
|
Register result = ToRegister(instr->result());
|
2053
2098
|
if (instr->hydrogen()->is_in_object()) {
|
2054
2099
|
__ mov(result, FieldOperand(object, instr->hydrogen()->offset()));
|
@@ -2059,13 +2104,76 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
|
|
2059
2104
|
}
|
2060
2105
|
|
2061
2106
|
|
2107
|
+
void LCodeGen::EmitLoadField(Register result,
|
2108
|
+
Register object,
|
2109
|
+
Handle<Map> type,
|
2110
|
+
Handle<String> name) {
|
2111
|
+
LookupResult lookup;
|
2112
|
+
type->LookupInDescriptors(NULL, *name, &lookup);
|
2113
|
+
ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
|
2114
|
+
int index = lookup.GetLocalFieldIndexFromMap(*type);
|
2115
|
+
int offset = index * kPointerSize;
|
2116
|
+
if (index < 0) {
|
2117
|
+
// Negative property indices are in-object properties, indexed
|
2118
|
+
// from the end of the fixed part of the object.
|
2119
|
+
__ mov(result, FieldOperand(object, offset + type->instance_size()));
|
2120
|
+
} else {
|
2121
|
+
// Non-negative property indices are in the properties array.
|
2122
|
+
__ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
|
2123
|
+
__ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
|
2124
|
+
}
|
2125
|
+
}
|
2126
|
+
|
2127
|
+
|
2128
|
+
void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
|
2129
|
+
Register object = ToRegister(instr->object());
|
2130
|
+
Register result = ToRegister(instr->result());
|
2131
|
+
|
2132
|
+
int map_count = instr->hydrogen()->types()->length();
|
2133
|
+
Handle<String> name = instr->hydrogen()->name();
|
2134
|
+
if (map_count == 0) {
|
2135
|
+
ASSERT(instr->hydrogen()->need_generic());
|
2136
|
+
__ mov(ecx, name);
|
2137
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
2138
|
+
CallCode(ic, RelocInfo::CODE_TARGET, instr, false);
|
2139
|
+
} else {
|
2140
|
+
NearLabel done;
|
2141
|
+
for (int i = 0; i < map_count - 1; ++i) {
|
2142
|
+
Handle<Map> map = instr->hydrogen()->types()->at(i);
|
2143
|
+
NearLabel next;
|
2144
|
+
__ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
|
2145
|
+
__ j(not_equal, &next);
|
2146
|
+
EmitLoadField(result, object, map, name);
|
2147
|
+
__ jmp(&done);
|
2148
|
+
__ bind(&next);
|
2149
|
+
}
|
2150
|
+
Handle<Map> map = instr->hydrogen()->types()->last();
|
2151
|
+
__ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
|
2152
|
+
if (instr->hydrogen()->need_generic()) {
|
2153
|
+
NearLabel generic;
|
2154
|
+
__ j(not_equal, &generic);
|
2155
|
+
EmitLoadField(result, object, map, name);
|
2156
|
+
__ jmp(&done);
|
2157
|
+
__ bind(&generic);
|
2158
|
+
__ mov(ecx, name);
|
2159
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
2160
|
+
CallCode(ic, RelocInfo::CODE_TARGET, instr, false);
|
2161
|
+
} else {
|
2162
|
+
DeoptimizeIf(not_equal, instr->environment());
|
2163
|
+
EmitLoadField(result, object, map, name);
|
2164
|
+
}
|
2165
|
+
__ bind(&done);
|
2166
|
+
}
|
2167
|
+
}
|
2168
|
+
|
2169
|
+
|
2062
2170
|
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
|
2063
2171
|
ASSERT(ToRegister(instr->context()).is(esi));
|
2064
2172
|
ASSERT(ToRegister(instr->object()).is(eax));
|
2065
2173
|
ASSERT(ToRegister(instr->result()).is(eax));
|
2066
2174
|
|
2067
2175
|
__ mov(ecx, instr->name());
|
2068
|
-
Handle<Code> ic(
|
2176
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
2069
2177
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2070
2178
|
}
|
2071
2179
|
|
@@ -2090,7 +2198,7 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
|
|
2090
2198
|
FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
2091
2199
|
|
2092
2200
|
// Check that the function has a prototype or an initial map.
|
2093
|
-
__ cmp(Operand(result), Immediate(
|
2201
|
+
__ cmp(Operand(result), Immediate(factory()->the_hole_value()));
|
2094
2202
|
DeoptimizeIf(equal, instr->environment());
|
2095
2203
|
|
2096
2204
|
// If the function does not have an initial map, we're done.
|
@@ -2119,24 +2227,30 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
|
|
2119
2227
|
if (FLAG_debug_code) {
|
2120
2228
|
NearLabel done;
|
2121
2229
|
__ cmp(FieldOperand(result, HeapObject::kMapOffset),
|
2122
|
-
Immediate(
|
2230
|
+
Immediate(factory()->fixed_array_map()));
|
2123
2231
|
__ j(equal, &done);
|
2124
2232
|
__ cmp(FieldOperand(result, HeapObject::kMapOffset),
|
2125
|
-
Immediate(
|
2233
|
+
Immediate(factory()->fixed_cow_array_map()));
|
2126
2234
|
__ j(equal, &done);
|
2127
|
-
|
2128
|
-
|
2129
|
-
__
|
2235
|
+
Register temp((result.is(eax)) ? ebx : eax);
|
2236
|
+
__ push(temp);
|
2237
|
+
__ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
|
2238
|
+
__ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
|
2239
|
+
__ sub(Operand(temp), Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
|
2240
|
+
__ cmp(Operand(temp), Immediate(kExternalArrayTypeCount));
|
2241
|
+
__ pop(temp);
|
2242
|
+
__ Check(below, "Check for fast elements or pixel array failed.");
|
2130
2243
|
__ bind(&done);
|
2131
2244
|
}
|
2132
2245
|
}
|
2133
2246
|
|
2134
2247
|
|
2135
|
-
void LCodeGen::
|
2136
|
-
|
2248
|
+
void LCodeGen::DoLoadExternalArrayPointer(
|
2249
|
+
LLoadExternalArrayPointer* instr) {
|
2137
2250
|
Register result = ToRegister(instr->result());
|
2138
2251
|
Register input = ToRegister(instr->InputAt(0));
|
2139
|
-
__ mov(result, FieldOperand(input,
|
2252
|
+
__ mov(result, FieldOperand(input,
|
2253
|
+
ExternalArray::kExternalPointerOffset));
|
2140
2254
|
}
|
2141
2255
|
|
2142
2256
|
|
@@ -2168,19 +2282,52 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
|
|
2168
2282
|
FixedArray::kHeaderSize));
|
2169
2283
|
|
2170
2284
|
// Check for the hole value.
|
2171
|
-
__ cmp(result,
|
2285
|
+
__ cmp(result, factory()->the_hole_value());
|
2172
2286
|
DeoptimizeIf(equal, instr->environment());
|
2173
2287
|
}
|
2174
2288
|
|
2175
2289
|
|
2176
|
-
void LCodeGen::
|
2290
|
+
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
|
2291
|
+
LLoadKeyedSpecializedArrayElement* instr) {
|
2177
2292
|
Register external_pointer = ToRegister(instr->external_pointer());
|
2178
2293
|
Register key = ToRegister(instr->key());
|
2179
|
-
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2294
|
+
ExternalArrayType array_type = instr->array_type();
|
2295
|
+
if (array_type == kExternalFloatArray) {
|
2296
|
+
XMMRegister result(ToDoubleRegister(instr->result()));
|
2297
|
+
__ movss(result, Operand(external_pointer, key, times_4, 0));
|
2298
|
+
__ cvtss2sd(result, result);
|
2299
|
+
} else {
|
2300
|
+
Register result(ToRegister(instr->result()));
|
2301
|
+
switch (array_type) {
|
2302
|
+
case kExternalByteArray:
|
2303
|
+
__ movsx_b(result, Operand(external_pointer, key, times_1, 0));
|
2304
|
+
break;
|
2305
|
+
case kExternalUnsignedByteArray:
|
2306
|
+
case kExternalPixelArray:
|
2307
|
+
__ movzx_b(result, Operand(external_pointer, key, times_1, 0));
|
2308
|
+
break;
|
2309
|
+
case kExternalShortArray:
|
2310
|
+
__ movsx_w(result, Operand(external_pointer, key, times_2, 0));
|
2311
|
+
break;
|
2312
|
+
case kExternalUnsignedShortArray:
|
2313
|
+
__ movzx_w(result, Operand(external_pointer, key, times_2, 0));
|
2314
|
+
break;
|
2315
|
+
case kExternalIntArray:
|
2316
|
+
__ mov(result, Operand(external_pointer, key, times_4, 0));
|
2317
|
+
break;
|
2318
|
+
case kExternalUnsignedIntArray:
|
2319
|
+
__ mov(result, Operand(external_pointer, key, times_4, 0));
|
2320
|
+
__ test(result, Operand(result));
|
2321
|
+
// TODO(danno): we could be more clever here, perhaps having a special
|
2322
|
+
// version of the stub that detects if the overflow case actually
|
2323
|
+
// happens, and generate code that returns a double rather than int.
|
2324
|
+
DeoptimizeIf(negative, instr->environment());
|
2325
|
+
break;
|
2326
|
+
case kExternalFloatArray:
|
2327
|
+
UNREACHABLE();
|
2328
|
+
break;
|
2329
|
+
}
|
2330
|
+
}
|
2184
2331
|
}
|
2185
2332
|
|
2186
2333
|
|
@@ -2189,7 +2336,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
|
|
2189
2336
|
ASSERT(ToRegister(instr->object()).is(edx));
|
2190
2337
|
ASSERT(ToRegister(instr->key()).is(eax));
|
2191
2338
|
|
2192
|
-
Handle<Code> ic(
|
2339
|
+
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
|
2193
2340
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2194
2341
|
}
|
2195
2342
|
|
@@ -2254,9 +2401,9 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
|
|
2254
2401
|
// If the receiver is null or undefined, we have to pass the global object
|
2255
2402
|
// as a receiver.
|
2256
2403
|
NearLabel global_object, receiver_ok;
|
2257
|
-
__ cmp(receiver,
|
2404
|
+
__ cmp(receiver, factory()->null_value());
|
2258
2405
|
__ j(equal, &global_object);
|
2259
|
-
__ cmp(receiver,
|
2406
|
+
__ cmp(receiver, factory()->undefined_value());
|
2260
2407
|
__ j(equal, &global_object);
|
2261
2408
|
|
2262
2409
|
// The receiver should be a JS object.
|
@@ -2303,8 +2450,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
|
|
2303
2450
|
RegisterEnvironmentForDeoptimization(env);
|
2304
2451
|
SafepointGenerator safepoint_generator(this,
|
2305
2452
|
pointers,
|
2306
|
-
env->deoptimization_index()
|
2307
|
-
true);
|
2453
|
+
env->deoptimization_index());
|
2308
2454
|
v8::internal::ParameterCount actual(eax);
|
2309
2455
|
__ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
|
2310
2456
|
}
|
@@ -2353,7 +2499,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
|
2353
2499
|
LInstruction* instr) {
|
2354
2500
|
// Change context if needed.
|
2355
2501
|
bool change_context =
|
2356
|
-
(
|
2502
|
+
(info()->closure()->context() != function->context()) ||
|
2357
2503
|
scope()->contains_with() ||
|
2358
2504
|
(scope()->num_heap_slots() > 0);
|
2359
2505
|
if (change_context) {
|
@@ -2372,11 +2518,10 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
|
2372
2518
|
RecordPosition(pointers->position());
|
2373
2519
|
|
2374
2520
|
// Invoke function.
|
2375
|
-
if (*function == *
|
2521
|
+
if (*function == *info()->closure()) {
|
2376
2522
|
__ CallSelf();
|
2377
2523
|
} else {
|
2378
2524
|
__ call(FieldOperand(edi, JSFunction::kCodeEntryOffset));
|
2379
|
-
EnsureRelocSpaceForDeoptimization();
|
2380
2525
|
}
|
2381
2526
|
|
2382
2527
|
// Setup deoptimization.
|
@@ -2394,7 +2539,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
|
|
2394
2539
|
void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
|
2395
2540
|
Register input_reg = ToRegister(instr->InputAt(0));
|
2396
2541
|
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
|
2397
|
-
|
2542
|
+
factory()->heap_number_map());
|
2398
2543
|
DeoptimizeIf(not_equal, instr->environment());
|
2399
2544
|
|
2400
2545
|
Label done;
|
@@ -2575,13 +2720,15 @@ void LCodeGen::DoPower(LPower* instr) {
|
|
2575
2720
|
LOperand* right = instr->InputAt(1);
|
2576
2721
|
DoubleRegister result_reg = ToDoubleRegister(instr->result());
|
2577
2722
|
Representation exponent_type = instr->hydrogen()->right()->representation();
|
2723
|
+
|
2578
2724
|
if (exponent_type.IsDouble()) {
|
2579
2725
|
// It is safe to use ebx directly since the instruction is marked
|
2580
2726
|
// as a call.
|
2581
2727
|
__ PrepareCallCFunction(4, ebx);
|
2582
2728
|
__ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
|
2583
2729
|
__ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
|
2584
|
-
__ CallCFunction(ExternalReference::power_double_double_function(),
|
2730
|
+
__ CallCFunction(ExternalReference::power_double_double_function(isolate()),
|
2731
|
+
4);
|
2585
2732
|
} else if (exponent_type.IsInteger32()) {
|
2586
2733
|
// It is safe to use ebx directly since the instruction is marked
|
2587
2734
|
// as a call.
|
@@ -2589,7 +2736,8 @@ void LCodeGen::DoPower(LPower* instr) {
|
|
2589
2736
|
__ PrepareCallCFunction(4, ebx);
|
2590
2737
|
__ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
|
2591
2738
|
__ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right));
|
2592
|
-
__ CallCFunction(ExternalReference::power_double_int_function(),
|
2739
|
+
__ CallCFunction(ExternalReference::power_double_int_function(isolate()),
|
2740
|
+
4);
|
2593
2741
|
} else {
|
2594
2742
|
ASSERT(exponent_type.IsTagged());
|
2595
2743
|
CpuFeatures::Scope scope(SSE2);
|
@@ -2614,7 +2762,8 @@ void LCodeGen::DoPower(LPower* instr) {
|
|
2614
2762
|
__ PrepareCallCFunction(4, ebx);
|
2615
2763
|
__ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
|
2616
2764
|
__ movdbl(Operand(esp, 1 * kDoubleSize), result_reg);
|
2617
|
-
__ CallCFunction(ExternalReference::power_double_double_function(),
|
2765
|
+
__ CallCFunction(ExternalReference::power_double_double_function(isolate()),
|
2766
|
+
4);
|
2618
2767
|
}
|
2619
2768
|
|
2620
2769
|
// Return value is in st(0) on ia32.
|
@@ -2689,7 +2838,8 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
|
|
2689
2838
|
ASSERT(ToRegister(instr->result()).is(eax));
|
2690
2839
|
|
2691
2840
|
int arity = instr->arity();
|
2692
|
-
Handle<Code> ic =
|
2841
|
+
Handle<Code> ic = isolate()->stub_cache()->
|
2842
|
+
ComputeKeyedCallInitialize(arity, NOT_IN_LOOP);
|
2693
2843
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2694
2844
|
}
|
2695
2845
|
|
@@ -2699,7 +2849,8 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) {
|
|
2699
2849
|
ASSERT(ToRegister(instr->result()).is(eax));
|
2700
2850
|
|
2701
2851
|
int arity = instr->arity();
|
2702
|
-
Handle<Code> ic =
|
2852
|
+
Handle<Code> ic = isolate()->stub_cache()->
|
2853
|
+
ComputeCallInitialize(arity, NOT_IN_LOOP);
|
2703
2854
|
__ mov(ecx, instr->name());
|
2704
2855
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2705
2856
|
}
|
@@ -2721,7 +2872,8 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
|
|
2721
2872
|
ASSERT(ToRegister(instr->result()).is(eax));
|
2722
2873
|
|
2723
2874
|
int arity = instr->arity();
|
2724
|
-
Handle<Code> ic =
|
2875
|
+
Handle<Code> ic = isolate()->stub_cache()->
|
2876
|
+
ComputeCallInitialize(arity, NOT_IN_LOOP);
|
2725
2877
|
__ mov(ecx, instr->name());
|
2726
2878
|
CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
|
2727
2879
|
}
|
@@ -2739,7 +2891,7 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
|
|
2739
2891
|
ASSERT(ToRegister(instr->constructor()).is(edi));
|
2740
2892
|
ASSERT(ToRegister(instr->result()).is(eax));
|
2741
2893
|
|
2742
|
-
Handle<Code> builtin(
|
2894
|
+
Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
|
2743
2895
|
__ Set(eax, Immediate(instr->arity()));
|
2744
2896
|
CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
|
2745
2897
|
}
|
@@ -2786,7 +2938,9 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
|
|
2786
2938
|
ASSERT(ToRegister(instr->value()).is(eax));
|
2787
2939
|
|
2788
2940
|
__ mov(ecx, instr->name());
|
2789
|
-
Handle<Code> ic(
|
2941
|
+
Handle<Code> ic = info_->is_strict()
|
2942
|
+
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
2943
|
+
: isolate()->builtins()->StoreIC_Initialize();
|
2790
2944
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2791
2945
|
}
|
2792
2946
|
|
@@ -2797,22 +2951,52 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
|
|
2797
2951
|
}
|
2798
2952
|
|
2799
2953
|
|
2800
|
-
void LCodeGen::
|
2954
|
+
void LCodeGen::DoStoreKeyedSpecializedArrayElement(
|
2955
|
+
LStoreKeyedSpecializedArrayElement* instr) {
|
2801
2956
|
Register external_pointer = ToRegister(instr->external_pointer());
|
2802
2957
|
Register key = ToRegister(instr->key());
|
2803
|
-
|
2804
|
-
|
2805
|
-
|
2806
|
-
|
2807
|
-
|
2808
|
-
|
2809
|
-
|
2810
|
-
|
2811
|
-
|
2812
|
-
|
2813
|
-
|
2958
|
+
ExternalArrayType array_type = instr->array_type();
|
2959
|
+
if (array_type == kExternalFloatArray) {
|
2960
|
+
__ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
|
2961
|
+
__ movss(Operand(external_pointer, key, times_4, 0), xmm0);
|
2962
|
+
} else {
|
2963
|
+
Register value = ToRegister(instr->value());
|
2964
|
+
switch (array_type) {
|
2965
|
+
case kExternalPixelArray: {
|
2966
|
+
// Clamp the value to [0..255].
|
2967
|
+
Register temp = ToRegister(instr->TempAt(0));
|
2968
|
+
// The dec_b below requires that the clamped value is in a byte
|
2969
|
+
// register. eax is an arbitrary choice to satisfy this requirement, we
|
2970
|
+
// hinted the register allocator to give us eax when building the
|
2971
|
+
// instruction.
|
2972
|
+
ASSERT(temp.is(eax));
|
2973
|
+
__ mov(temp, ToRegister(instr->value()));
|
2974
|
+
NearLabel done;
|
2975
|
+
__ test(temp, Immediate(0xFFFFFF00));
|
2976
|
+
__ j(zero, &done);
|
2977
|
+
__ setcc(negative, temp); // 1 if negative, 0 if positive.
|
2978
|
+
__ dec_b(temp); // 0 if negative, 255 if positive.
|
2979
|
+
__ bind(&done);
|
2980
|
+
__ mov_b(Operand(external_pointer, key, times_1, 0), temp);
|
2981
|
+
break;
|
2982
|
+
}
|
2983
|
+
case kExternalByteArray:
|
2984
|
+
case kExternalUnsignedByteArray:
|
2985
|
+
__ mov_b(Operand(external_pointer, key, times_1, 0), value);
|
2986
|
+
break;
|
2987
|
+
case kExternalShortArray:
|
2988
|
+
case kExternalUnsignedShortArray:
|
2989
|
+
__ mov_w(Operand(external_pointer, key, times_2, 0), value);
|
2990
|
+
break;
|
2991
|
+
case kExternalIntArray:
|
2992
|
+
case kExternalUnsignedIntArray:
|
2993
|
+
__ mov(Operand(external_pointer, key, times_4, 0), value);
|
2994
|
+
break;
|
2995
|
+
case kExternalFloatArray:
|
2996
|
+
UNREACHABLE();
|
2997
|
+
break;
|
2998
|
+
}
|
2814
2999
|
}
|
2815
|
-
__ mov_b(Operand(external_pointer, key, times_1, 0), eax);
|
2816
3000
|
}
|
2817
3001
|
|
2818
3002
|
|
@@ -2854,7 +3038,9 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
|
|
2854
3038
|
ASSERT(ToRegister(instr->key()).is(ecx));
|
2855
3039
|
ASSERT(ToRegister(instr->value()).is(eax));
|
2856
3040
|
|
2857
|
-
Handle<Code> ic(
|
3041
|
+
Handle<Code> ic = info_->is_strict()
|
3042
|
+
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
|
3043
|
+
: isolate()->builtins()->KeyedStoreIC_Initialize();
|
2858
3044
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
2859
3045
|
}
|
2860
3046
|
|
@@ -2914,7 +3100,7 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
|
|
2914
3100
|
// the case we would rather go to the runtime system now to flatten
|
2915
3101
|
// the string.
|
2916
3102
|
__ cmp(FieldOperand(string, ConsString::kSecondOffset),
|
2917
|
-
Immediate(
|
3103
|
+
Immediate(factory()->empty_string()));
|
2918
3104
|
__ j(not_equal, deferred->entry());
|
2919
3105
|
// Get the first of the two strings and load its instance type.
|
2920
3106
|
__ mov(string, FieldOperand(string, ConsString::kFirstOffset));
|
@@ -2999,6 +3185,56 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
|
|
2999
3185
|
}
|
3000
3186
|
|
3001
3187
|
|
3188
|
+
void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
|
3189
|
+
class DeferredStringCharFromCode: public LDeferredCode {
|
3190
|
+
public:
|
3191
|
+
DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
|
3192
|
+
: LDeferredCode(codegen), instr_(instr) { }
|
3193
|
+
virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); }
|
3194
|
+
private:
|
3195
|
+
LStringCharFromCode* instr_;
|
3196
|
+
};
|
3197
|
+
|
3198
|
+
DeferredStringCharFromCode* deferred =
|
3199
|
+
new DeferredStringCharFromCode(this, instr);
|
3200
|
+
|
3201
|
+
ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
|
3202
|
+
Register char_code = ToRegister(instr->char_code());
|
3203
|
+
Register result = ToRegister(instr->result());
|
3204
|
+
ASSERT(!char_code.is(result));
|
3205
|
+
|
3206
|
+
__ cmp(char_code, String::kMaxAsciiCharCode);
|
3207
|
+
__ j(above, deferred->entry());
|
3208
|
+
__ Set(result, Immediate(factory()->single_character_string_cache()));
|
3209
|
+
__ mov(result, FieldOperand(result,
|
3210
|
+
char_code, times_pointer_size,
|
3211
|
+
FixedArray::kHeaderSize));
|
3212
|
+
__ cmp(result, factory()->undefined_value());
|
3213
|
+
__ j(equal, deferred->entry());
|
3214
|
+
__ bind(deferred->exit());
|
3215
|
+
}
|
3216
|
+
|
3217
|
+
|
3218
|
+
void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
|
3219
|
+
Register char_code = ToRegister(instr->char_code());
|
3220
|
+
Register result = ToRegister(instr->result());
|
3221
|
+
|
3222
|
+
// TODO(3095996): Get rid of this. For now, we need to make the
|
3223
|
+
// result register contain a valid pointer because it is already
|
3224
|
+
// contained in the register pointer map.
|
3225
|
+
__ Set(result, Immediate(0));
|
3226
|
+
|
3227
|
+
__ PushSafepointRegisters();
|
3228
|
+
__ SmiTag(char_code);
|
3229
|
+
__ push(char_code);
|
3230
|
+
__ CallRuntimeSaveDoubles(Runtime::kCharFromCode);
|
3231
|
+
RecordSafepointWithRegisters(
|
3232
|
+
instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex);
|
3233
|
+
__ StoreToSafepointRegisterSlot(result, eax);
|
3234
|
+
__ PopSafepointRegisters();
|
3235
|
+
}
|
3236
|
+
|
3237
|
+
|
3002
3238
|
void LCodeGen::DoStringLength(LStringLength* instr) {
|
3003
3239
|
Register string = ToRegister(instr->string());
|
3004
3240
|
Register result = ToRegister(instr->result());
|
@@ -3151,17 +3387,15 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
|
|
3151
3387
|
|
3152
3388
|
// Heap number map check.
|
3153
3389
|
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
|
3154
|
-
|
3390
|
+
factory()->heap_number_map());
|
3155
3391
|
__ j(equal, &heap_number);
|
3156
3392
|
|
3157
|
-
__ cmp(input_reg,
|
3393
|
+
__ cmp(input_reg, factory()->undefined_value());
|
3158
3394
|
DeoptimizeIf(not_equal, env);
|
3159
3395
|
|
3160
3396
|
// Convert undefined to NaN.
|
3161
|
-
|
3162
|
-
__
|
3163
|
-
__ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
3164
|
-
__ pop(input_reg);
|
3397
|
+
ExternalReference nan = ExternalReference::address_of_nan();
|
3398
|
+
__ movdbl(result_reg, Operand::StaticVariable(nan));
|
3165
3399
|
__ jmp(&done);
|
3166
3400
|
|
3167
3401
|
// Heap number to XMM conversion.
|
@@ -3194,13 +3428,13 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
|
3194
3428
|
|
3195
3429
|
// Heap number map check.
|
3196
3430
|
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
|
3197
|
-
|
3431
|
+
factory()->heap_number_map());
|
3198
3432
|
|
3199
3433
|
if (instr->truncating()) {
|
3200
3434
|
__ j(equal, &heap_number);
|
3201
3435
|
// Check for undefined. Undefined is converted to zero for truncating
|
3202
3436
|
// conversions.
|
3203
|
-
__ cmp(input_reg,
|
3437
|
+
__ cmp(input_reg, factory()->undefined_value());
|
3204
3438
|
DeoptimizeIf(not_equal, instr->environment());
|
3205
3439
|
__ mov(input_reg, 0);
|
3206
3440
|
__ jmp(&done);
|
@@ -3421,9 +3655,15 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
|
|
3421
3655
|
|
3422
3656
|
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
|
3423
3657
|
LOperand* input = instr->InputAt(0);
|
3424
|
-
ASSERT(input->IsRegister());
|
3425
3658
|
__ test(ToRegister(input), Immediate(kSmiTagMask));
|
3426
|
-
DeoptimizeIf(
|
3659
|
+
DeoptimizeIf(not_zero, instr->environment());
|
3660
|
+
}
|
3661
|
+
|
3662
|
+
|
3663
|
+
void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
|
3664
|
+
LOperand* input = instr->InputAt(0);
|
3665
|
+
__ test(ToRegister(input), Immediate(kSmiTagMask));
|
3666
|
+
DeoptimizeIf(zero, instr->environment());
|
3427
3667
|
}
|
3428
3668
|
|
3429
3669
|
|
@@ -3477,9 +3717,9 @@ void LCodeGen::DoCheckMap(LCheckMap* instr) {
|
|
3477
3717
|
|
3478
3718
|
|
3479
3719
|
void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) {
|
3480
|
-
if (
|
3720
|
+
if (isolate()->heap()->InNewSpace(*object)) {
|
3481
3721
|
Handle<JSGlobalPropertyCell> cell =
|
3482
|
-
|
3722
|
+
isolate()->factory()->NewJSGlobalPropertyCell(object);
|
3483
3723
|
__ mov(result, Operand::Cell(cell));
|
3484
3724
|
} else {
|
3485
3725
|
__ mov(result, object);
|
@@ -3549,7 +3789,13 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
|
|
3549
3789
|
__ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
|
3550
3790
|
__ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
|
3551
3791
|
__ push(Immediate(instr->hydrogen()->constant_properties()));
|
3552
|
-
|
3792
|
+
int flags = instr->hydrogen()->fast_elements()
|
3793
|
+
? ObjectLiteral::kFastElements
|
3794
|
+
: ObjectLiteral::kNoFlags;
|
3795
|
+
flags |= instr->hydrogen()->has_function()
|
3796
|
+
? ObjectLiteral::kHasFunction
|
3797
|
+
: ObjectLiteral::kNoFlags;
|
3798
|
+
__ push(Immediate(Smi::FromInt(flags)));
|
3553
3799
|
|
3554
3800
|
// Pick the right runtime function to call.
|
3555
3801
|
if (instr->hydrogen()->depth() > 1) {
|
@@ -3560,6 +3806,13 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
|
|
3560
3806
|
}
|
3561
3807
|
|
3562
3808
|
|
3809
|
+
void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
|
3810
|
+
ASSERT(ToRegister(instr->InputAt(0)).is(eax));
|
3811
|
+
__ push(eax);
|
3812
|
+
CallRuntime(Runtime::kToFastProperties, 1, instr);
|
3813
|
+
}
|
3814
|
+
|
3815
|
+
|
3563
3816
|
void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
|
3564
3817
|
NearLabel materialized;
|
3565
3818
|
// Registers will be used as follows:
|
@@ -3572,7 +3825,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
|
|
3572
3825
|
int literal_offset = FixedArray::kHeaderSize +
|
3573
3826
|
instr->hydrogen()->literal_index() * kPointerSize;
|
3574
3827
|
__ mov(ebx, FieldOperand(ecx, literal_offset));
|
3575
|
-
__ cmp(ebx,
|
3828
|
+
__ cmp(ebx, factory()->undefined_value());
|
3576
3829
|
__ j(not_equal, &materialized);
|
3577
3830
|
|
3578
3831
|
// Create regexp literal using runtime function
|
@@ -3617,16 +3870,17 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
|
|
3617
3870
|
// space for nested functions that don't need literals cloning.
|
3618
3871
|
Handle<SharedFunctionInfo> shared_info = instr->shared_info();
|
3619
3872
|
bool pretenure = instr->hydrogen()->pretenure();
|
3620
|
-
if (shared_info->num_literals() == 0
|
3621
|
-
FastNewClosureStub stub
|
3873
|
+
if (!pretenure && shared_info->num_literals() == 0) {
|
3874
|
+
FastNewClosureStub stub(
|
3875
|
+
shared_info->strict_mode() ? kStrictMode : kNonStrictMode);
|
3622
3876
|
__ push(Immediate(shared_info));
|
3623
3877
|
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false);
|
3624
3878
|
} else {
|
3625
3879
|
__ push(Operand(ebp, StandardFrameConstants::kContextOffset));
|
3626
3880
|
__ push(Immediate(shared_info));
|
3627
3881
|
__ push(Immediate(pretenure
|
3628
|
-
?
|
3629
|
-
:
|
3882
|
+
? factory()->true_value()
|
3883
|
+
: factory()->false_value()));
|
3630
3884
|
CallRuntime(Runtime::kNewClosure, 3, instr, false);
|
3631
3885
|
}
|
3632
3886
|
}
|
@@ -3656,11 +3910,11 @@ void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
|
|
3656
3910
|
instr->type_literal());
|
3657
3911
|
__ j(final_branch_condition, &true_label);
|
3658
3912
|
__ bind(&false_label);
|
3659
|
-
__ mov(result,
|
3913
|
+
__ mov(result, factory()->false_value());
|
3660
3914
|
__ jmp(&done);
|
3661
3915
|
|
3662
3916
|
__ bind(&true_label);
|
3663
|
-
__ mov(result,
|
3917
|
+
__ mov(result, factory()->true_value());
|
3664
3918
|
|
3665
3919
|
__ bind(&done);
|
3666
3920
|
}
|
@@ -3687,66 +3941,57 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
|
|
3687
3941
|
Register input,
|
3688
3942
|
Handle<String> type_name) {
|
3689
3943
|
Condition final_branch_condition = no_condition;
|
3690
|
-
if (type_name->Equals(
|
3691
|
-
__
|
3692
|
-
__ j(zero, true_label);
|
3944
|
+
if (type_name->Equals(heap()->number_symbol())) {
|
3945
|
+
__ JumpIfSmi(input, true_label);
|
3693
3946
|
__ cmp(FieldOperand(input, HeapObject::kMapOffset),
|
3694
|
-
|
3947
|
+
factory()->heap_number_map());
|
3695
3948
|
final_branch_condition = equal;
|
3696
3949
|
|
3697
|
-
} else if (type_name->Equals(
|
3698
|
-
__
|
3699
|
-
__
|
3700
|
-
__
|
3950
|
+
} else if (type_name->Equals(heap()->string_symbol())) {
|
3951
|
+
__ JumpIfSmi(input, false_label);
|
3952
|
+
__ CmpObjectType(input, FIRST_NONSTRING_TYPE, input);
|
3953
|
+
__ j(above_equal, false_label);
|
3701
3954
|
__ test_b(FieldOperand(input, Map::kBitFieldOffset),
|
3702
3955
|
1 << Map::kIsUndetectable);
|
3703
|
-
|
3704
|
-
__ CmpInstanceType(input, FIRST_NONSTRING_TYPE);
|
3705
|
-
final_branch_condition = below;
|
3956
|
+
final_branch_condition = zero;
|
3706
3957
|
|
3707
|
-
} else if (type_name->Equals(
|
3708
|
-
__ cmp(input,
|
3958
|
+
} else if (type_name->Equals(heap()->boolean_symbol())) {
|
3959
|
+
__ cmp(input, factory()->true_value());
|
3709
3960
|
__ j(equal, true_label);
|
3710
|
-
__ cmp(input,
|
3961
|
+
__ cmp(input, factory()->false_value());
|
3711
3962
|
final_branch_condition = equal;
|
3712
3963
|
|
3713
|
-
} else if (type_name->Equals(
|
3714
|
-
__ cmp(input,
|
3964
|
+
} else if (type_name->Equals(heap()->undefined_symbol())) {
|
3965
|
+
__ cmp(input, factory()->undefined_value());
|
3715
3966
|
__ j(equal, true_label);
|
3716
|
-
__
|
3717
|
-
__ j(zero, false_label);
|
3967
|
+
__ JumpIfSmi(input, false_label);
|
3718
3968
|
// Check for undetectable objects => true.
|
3719
3969
|
__ mov(input, FieldOperand(input, HeapObject::kMapOffset));
|
3720
3970
|
__ test_b(FieldOperand(input, Map::kBitFieldOffset),
|
3721
3971
|
1 << Map::kIsUndetectable);
|
3722
3972
|
final_branch_condition = not_zero;
|
3723
3973
|
|
3724
|
-
} else if (type_name->Equals(
|
3725
|
-
__
|
3726
|
-
__ j(zero, false_label);
|
3974
|
+
} else if (type_name->Equals(heap()->function_symbol())) {
|
3975
|
+
__ JumpIfSmi(input, false_label);
|
3727
3976
|
__ CmpObjectType(input, JS_FUNCTION_TYPE, input);
|
3728
3977
|
__ j(equal, true_label);
|
3729
3978
|
// Regular expressions => 'function' (they are callable).
|
3730
3979
|
__ CmpInstanceType(input, JS_REGEXP_TYPE);
|
3731
3980
|
final_branch_condition = equal;
|
3732
3981
|
|
3733
|
-
} else if (type_name->Equals(
|
3734
|
-
__
|
3735
|
-
__
|
3736
|
-
__ cmp(input, Factory::null_value());
|
3982
|
+
} else if (type_name->Equals(heap()->object_symbol())) {
|
3983
|
+
__ JumpIfSmi(input, false_label);
|
3984
|
+
__ cmp(input, factory()->null_value());
|
3737
3985
|
__ j(equal, true_label);
|
3738
3986
|
// Regular expressions => 'function', not 'object'.
|
3739
|
-
__ CmpObjectType(input,
|
3740
|
-
__ j(
|
3987
|
+
__ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input);
|
3988
|
+
__ j(below, false_label);
|
3989
|
+
__ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
|
3990
|
+
__ j(above_equal, false_label);
|
3741
3991
|
// Check for undetectable objects => false.
|
3742
3992
|
__ test_b(FieldOperand(input, Map::kBitFieldOffset),
|
3743
3993
|
1 << Map::kIsUndetectable);
|
3744
|
-
|
3745
|
-
// Check for JS objects => true.
|
3746
|
-
__ CmpInstanceType(input, FIRST_JS_OBJECT_TYPE);
|
3747
|
-
__ j(below, false_label);
|
3748
|
-
__ CmpInstanceType(input, LAST_JS_OBJECT_TYPE);
|
3749
|
-
final_branch_condition = below_equal;
|
3994
|
+
final_branch_condition = zero;
|
3750
3995
|
|
3751
3996
|
} else {
|
3752
3997
|
final_branch_condition = not_equal;
|
@@ -3767,11 +4012,11 @@ void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
|
|
3767
4012
|
EmitIsConstructCall(result);
|
3768
4013
|
__ j(equal, &true_label);
|
3769
4014
|
|
3770
|
-
__ mov(result,
|
4015
|
+
__ mov(result, factory()->false_value());
|
3771
4016
|
__ jmp(&done);
|
3772
4017
|
|
3773
4018
|
__ bind(&true_label);
|
3774
|
-
__ mov(result,
|
4019
|
+
__ mov(result, factory()->true_value());
|
3775
4020
|
|
3776
4021
|
__ bind(&done);
|
3777
4022
|
}
|
@@ -3835,8 +4080,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
|
|
3835
4080
|
// builtin)
|
3836
4081
|
SafepointGenerator safepoint_generator(this,
|
3837
4082
|
pointers,
|
3838
|
-
env->deoptimization_index()
|
3839
|
-
true);
|
4083
|
+
env->deoptimization_index());
|
3840
4084
|
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
3841
4085
|
__ push(Immediate(Smi::FromInt(strict_mode_flag())));
|
3842
4086
|
__ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
|
@@ -3846,7 +4090,8 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
|
|
3846
4090
|
void LCodeGen::DoStackCheck(LStackCheck* instr) {
|
3847
4091
|
// Perform stack overflow check.
|
3848
4092
|
NearLabel done;
|
3849
|
-
ExternalReference stack_limit =
|
4093
|
+
ExternalReference stack_limit =
|
4094
|
+
ExternalReference::address_of_stack_limit(isolate());
|
3850
4095
|
__ cmp(esp, Operand::StaticVariable(stack_limit));
|
3851
4096
|
__ j(above_equal, &done);
|
3852
4097
|
|