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
@@ -56,7 +56,11 @@ class PostCallGenerator;
|
|
56
56
|
// MacroAssembler implements a collection of frequently used macros.
|
57
57
|
class MacroAssembler: public Assembler {
|
58
58
|
public:
|
59
|
-
|
59
|
+
// The isolate parameter can be NULL if the macro assembler should
|
60
|
+
// not use isolate-dependent functionality. In this case, it's the
|
61
|
+
// responsibility of the caller to never invoke such function on the
|
62
|
+
// macro assembler.
|
63
|
+
MacroAssembler(Isolate* isolate, void* buffer, int size);
|
60
64
|
|
61
65
|
// ---------------------------------------------------------------------------
|
62
66
|
// GC Support
|
@@ -474,13 +478,13 @@ class MacroAssembler: public Assembler {
|
|
474
478
|
void StubReturn(int argc);
|
475
479
|
|
476
480
|
// Call a runtime routine.
|
477
|
-
void CallRuntime(Runtime::Function* f, int num_arguments);
|
481
|
+
void CallRuntime(const Runtime::Function* f, int num_arguments);
|
478
482
|
void CallRuntimeSaveDoubles(Runtime::FunctionId id);
|
479
483
|
|
480
484
|
// Call a runtime function, returning the CodeStub object called.
|
481
485
|
// Try to generate the stub code if necessary. Do not perform a GC
|
482
486
|
// but instead return a retry after GC failure.
|
483
|
-
MUST_USE_RESULT MaybeObject* TryCallRuntime(Runtime::Function* f,
|
487
|
+
MUST_USE_RESULT MaybeObject* TryCallRuntime(const Runtime::Function* f,
|
484
488
|
int num_arguments);
|
485
489
|
|
486
490
|
// Convenience function: Same as above, but takes the fid instead.
|
@@ -580,7 +584,10 @@ class MacroAssembler: public Assembler {
|
|
580
584
|
|
581
585
|
void Move(Register target, Handle<Object> value);
|
582
586
|
|
583
|
-
Handle<Object> CodeObject() {
|
587
|
+
Handle<Object> CodeObject() {
|
588
|
+
ASSERT(!code_object_.is_null());
|
589
|
+
return code_object_;
|
590
|
+
}
|
584
591
|
|
585
592
|
|
586
593
|
// ---------------------------------------------------------------------------
|
@@ -646,7 +653,7 @@ class MacroAssembler: public Assembler {
|
|
646
653
|
const ParameterCount& actual,
|
647
654
|
Handle<Code> code_constant,
|
648
655
|
const Operand& code_operand,
|
649
|
-
|
656
|
+
NearLabel* done,
|
650
657
|
InvokeFlag flag,
|
651
658
|
PostCallGenerator* post_call_generator = NULL);
|
652
659
|
|
@@ -695,14 +702,16 @@ void MacroAssembler::InNewSpace(Register object,
|
|
695
702
|
// The mask isn't really an address. We load it as an external reference in
|
696
703
|
// case the size of the new space is different between the snapshot maker
|
697
704
|
// and the running system.
|
698
|
-
and_(Operand(scratch),
|
699
|
-
|
705
|
+
and_(Operand(scratch),
|
706
|
+
Immediate(ExternalReference::new_space_mask(isolate())));
|
707
|
+
cmp(Operand(scratch),
|
708
|
+
Immediate(ExternalReference::new_space_start(isolate())));
|
700
709
|
j(cc, branch);
|
701
710
|
} else {
|
702
711
|
int32_t new_space_start = reinterpret_cast<int32_t>(
|
703
|
-
ExternalReference::new_space_start().address());
|
712
|
+
ExternalReference::new_space_start(isolate()).address());
|
704
713
|
lea(scratch, Operand(object, -new_space_start));
|
705
|
-
and_(scratch,
|
714
|
+
and_(scratch, isolate()->heap()->NewSpaceMask());
|
706
715
|
j(cc, branch);
|
707
716
|
}
|
708
717
|
}
|
@@ -56,6 +56,7 @@ namespace internal {
|
|
56
56
|
*
|
57
57
|
* Each call to a public method should retain this convention.
|
58
58
|
* The stack will have the following structure:
|
59
|
+
* - Isolate* isolate (Address of the current isolate)
|
59
60
|
* - direct_call (if 1, direct call from JavaScript code, if 0
|
60
61
|
* call through the runtime system)
|
61
62
|
* - stack_area_base (High end of the memory area to use as
|
@@ -98,7 +99,7 @@ namespace internal {
|
|
98
99
|
RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32(
|
99
100
|
Mode mode,
|
100
101
|
int registers_to_save)
|
101
|
-
: masm_(new MacroAssembler(NULL, kRegExpCodeSize)),
|
102
|
+
: masm_(new MacroAssembler(Isolate::Current(), NULL, kRegExpCodeSize)),
|
102
103
|
mode_(mode),
|
103
104
|
num_registers_(registers_to_save),
|
104
105
|
num_saved_registers_(registers_to_save),
|
@@ -371,14 +372,18 @@ void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase(
|
|
371
372
|
__ push(backtrack_stackpointer());
|
372
373
|
__ push(ebx);
|
373
374
|
|
374
|
-
static const int argument_count =
|
375
|
+
static const int argument_count = 4;
|
375
376
|
__ PrepareCallCFunction(argument_count, ecx);
|
376
377
|
// Put arguments into allocated stack area, last argument highest on stack.
|
377
378
|
// Parameters are
|
378
379
|
// Address byte_offset1 - Address captured substring's start.
|
379
380
|
// Address byte_offset2 - Address of current character position.
|
380
381
|
// size_t byte_length - length of capture in bytes(!)
|
382
|
+
// Isolate* isolate
|
381
383
|
|
384
|
+
// Set isolate.
|
385
|
+
__ mov(Operand(esp, 3 * kPointerSize),
|
386
|
+
Immediate(ExternalReference::isolate_address()));
|
382
387
|
// Set byte_length.
|
383
388
|
__ mov(Operand(esp, 2 * kPointerSize), ebx);
|
384
389
|
// Set byte_offset2.
|
@@ -392,7 +397,7 @@ void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase(
|
|
392
397
|
__ mov(Operand(esp, 0 * kPointerSize), edx);
|
393
398
|
|
394
399
|
ExternalReference compare =
|
395
|
-
ExternalReference::re_case_insensitive_compare_uc16();
|
400
|
+
ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
|
396
401
|
__ CallCFunction(compare, argument_count);
|
397
402
|
// Pop original values before reacting on result value.
|
398
403
|
__ pop(ebx);
|
@@ -678,7 +683,7 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
678
683
|
Label stack_ok;
|
679
684
|
|
680
685
|
ExternalReference stack_limit =
|
681
|
-
ExternalReference::address_of_stack_limit();
|
686
|
+
ExternalReference::address_of_stack_limit(masm_->isolate());
|
682
687
|
__ mov(ecx, esp);
|
683
688
|
__ sub(ecx, Operand::StaticVariable(stack_limit));
|
684
689
|
// Handle it if the stack pointer is already below the stack limit.
|
@@ -837,12 +842,15 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
837
842
|
__ push(edi);
|
838
843
|
|
839
844
|
// Call GrowStack(backtrack_stackpointer())
|
840
|
-
static const int num_arguments =
|
845
|
+
static const int num_arguments = 3;
|
841
846
|
__ PrepareCallCFunction(num_arguments, ebx);
|
847
|
+
__ mov(Operand(esp, 2 * kPointerSize),
|
848
|
+
Immediate(ExternalReference::isolate_address()));
|
842
849
|
__ lea(eax, Operand(ebp, kStackHighEnd));
|
843
850
|
__ mov(Operand(esp, 1 * kPointerSize), eax);
|
844
851
|
__ mov(Operand(esp, 0 * kPointerSize), backtrack_stackpointer());
|
845
|
-
ExternalReference grow_stack =
|
852
|
+
ExternalReference grow_stack =
|
853
|
+
ExternalReference::re_grow_stack(masm_->isolate());
|
846
854
|
__ CallCFunction(grow_stack, num_arguments);
|
847
855
|
// If return NULL, we have failed to grow the stack, and
|
848
856
|
// must exit with a stack-overflow exception.
|
@@ -866,10 +874,11 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
866
874
|
|
867
875
|
CodeDesc code_desc;
|
868
876
|
masm_->GetCode(&code_desc);
|
869
|
-
Handle<Code> code =
|
870
|
-
|
871
|
-
|
872
|
-
|
877
|
+
Handle<Code> code =
|
878
|
+
masm_->isolate()->factory()->NewCode(code_desc,
|
879
|
+
Code::ComputeFlags(Code::REGEXP),
|
880
|
+
masm_->CodeObject());
|
881
|
+
PROFILE(masm_->isolate(), RegExpCodeCreateEvent(*code, *source));
|
873
882
|
return Handle<Object>::cast(code);
|
874
883
|
}
|
875
884
|
|
@@ -1024,7 +1033,7 @@ void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) {
|
|
1024
1033
|
__ lea(eax, Operand(esp, -kPointerSize));
|
1025
1034
|
__ mov(Operand(esp, 0 * kPointerSize), eax);
|
1026
1035
|
ExternalReference check_stack_guard =
|
1027
|
-
ExternalReference::re_check_stack_guard_state();
|
1036
|
+
ExternalReference::re_check_stack_guard_state(masm_->isolate());
|
1028
1037
|
__ CallCFunction(check_stack_guard, num_arguments);
|
1029
1038
|
}
|
1030
1039
|
|
@@ -1039,8 +1048,10 @@ static T& frame_entry(Address re_frame, int frame_offset) {
|
|
1039
1048
|
int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address,
|
1040
1049
|
Code* re_code,
|
1041
1050
|
Address re_frame) {
|
1042
|
-
|
1043
|
-
|
1051
|
+
Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate);
|
1052
|
+
ASSERT(isolate == Isolate::Current());
|
1053
|
+
if (isolate->stack_guard()->IsStackOverflow()) {
|
1054
|
+
isolate->StackOverflow();
|
1044
1055
|
return EXCEPTION;
|
1045
1056
|
}
|
1046
1057
|
|
@@ -1196,7 +1207,7 @@ void RegExpMacroAssemblerIA32::CheckPreemption() {
|
|
1196
1207
|
// Check for preemption.
|
1197
1208
|
Label no_preempt;
|
1198
1209
|
ExternalReference stack_limit =
|
1199
|
-
ExternalReference::address_of_stack_limit();
|
1210
|
+
ExternalReference::address_of_stack_limit(masm_->isolate());
|
1200
1211
|
__ cmp(esp, Operand::StaticVariable(stack_limit));
|
1201
1212
|
__ j(above, &no_preempt, taken);
|
1202
1213
|
|
@@ -1209,7 +1220,7 @@ void RegExpMacroAssemblerIA32::CheckPreemption() {
|
|
1209
1220
|
void RegExpMacroAssemblerIA32::CheckStackLimit() {
|
1210
1221
|
Label no_stack_overflow;
|
1211
1222
|
ExternalReference stack_limit =
|
1212
|
-
ExternalReference::address_of_regexp_stack_limit();
|
1223
|
+
ExternalReference::address_of_regexp_stack_limit(masm_->isolate());
|
1213
1224
|
__ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit));
|
1214
1225
|
__ j(above, &no_stack_overflow);
|
1215
1226
|
|
@@ -126,6 +126,7 @@ class RegExpMacroAssemblerIA32: public NativeRegExpMacroAssembler {
|
|
126
126
|
static const int kRegisterOutput = kInputEnd + kPointerSize;
|
127
127
|
static const int kStackHighEnd = kRegisterOutput + kPointerSize;
|
128
128
|
static const int kDirectCall = kStackHighEnd + kPointerSize;
|
129
|
+
static const int kIsolate = kDirectCall + kPointerSize;
|
129
130
|
// Below the frame pointer - local stack variables.
|
130
131
|
// When adding local variables remember to push space for them in
|
131
132
|
// the frame in GetCode.
|
@@ -42,12 +42,14 @@ namespace internal {
|
|
42
42
|
void Result::ToRegister() {
|
43
43
|
ASSERT(is_valid());
|
44
44
|
if (is_constant()) {
|
45
|
-
|
45
|
+
CodeGenerator* code_generator =
|
46
|
+
CodeGeneratorScope::Current(Isolate::Current());
|
47
|
+
Result fresh = code_generator->allocator()->Allocate();
|
46
48
|
ASSERT(fresh.is_valid());
|
47
49
|
if (is_untagged_int32()) {
|
48
50
|
fresh.set_untagged_int32(true);
|
49
51
|
if (handle()->IsSmi()) {
|
50
|
-
|
52
|
+
code_generator->masm()->Set(
|
51
53
|
fresh.reg(),
|
52
54
|
Immediate(Smi::cast(*handle())->value()));
|
53
55
|
} else if (handle()->IsHeapNumber()) {
|
@@ -56,25 +58,23 @@ void Result::ToRegister() {
|
|
56
58
|
if (double_value == 0 && signbit(double_value)) {
|
57
59
|
// Negative zero must not be converted to an int32 unless
|
58
60
|
// the context allows it.
|
59
|
-
|
60
|
-
|
61
|
+
code_generator->unsafe_bailout_->Branch(equal);
|
62
|
+
code_generator->unsafe_bailout_->Branch(not_equal);
|
61
63
|
} else if (double_value == value) {
|
62
|
-
|
63
|
-
fresh.reg(), Immediate(value));
|
64
|
+
code_generator->masm()->Set(fresh.reg(), Immediate(value));
|
64
65
|
} else {
|
65
|
-
|
66
|
-
|
66
|
+
code_generator->unsafe_bailout_->Branch(equal);
|
67
|
+
code_generator->unsafe_bailout_->Branch(not_equal);
|
67
68
|
}
|
68
69
|
} else {
|
69
70
|
// Constant is not a number. This was not predicted by AST analysis.
|
70
|
-
|
71
|
-
|
71
|
+
code_generator->unsafe_bailout_->Branch(equal);
|
72
|
+
code_generator->unsafe_bailout_->Branch(not_equal);
|
72
73
|
}
|
73
|
-
} else if (
|
74
|
-
|
74
|
+
} else if (code_generator->IsUnsafeSmi(handle())) {
|
75
|
+
code_generator->MoveUnsafeSmi(fresh.reg(), handle());
|
75
76
|
} else {
|
76
|
-
|
77
|
-
Immediate(handle()));
|
77
|
+
code_generator->masm()->Set(fresh.reg(), Immediate(handle()));
|
78
78
|
}
|
79
79
|
// This result becomes a copy of the fresh one.
|
80
80
|
fresh.set_type_info(type_info());
|
@@ -85,17 +85,19 @@ void Result::ToRegister() {
|
|
85
85
|
|
86
86
|
|
87
87
|
void Result::ToRegister(Register target) {
|
88
|
+
CodeGenerator* code_generator =
|
89
|
+
CodeGeneratorScope::Current(Isolate::Current());
|
88
90
|
ASSERT(is_valid());
|
89
91
|
if (!is_register() || !reg().is(target)) {
|
90
|
-
Result fresh =
|
92
|
+
Result fresh = code_generator->allocator()->Allocate(target);
|
91
93
|
ASSERT(fresh.is_valid());
|
92
94
|
if (is_register()) {
|
93
|
-
|
95
|
+
code_generator->masm()->mov(fresh.reg(), reg());
|
94
96
|
} else {
|
95
97
|
ASSERT(is_constant());
|
96
98
|
if (is_untagged_int32()) {
|
97
99
|
if (handle()->IsSmi()) {
|
98
|
-
|
100
|
+
code_generator->masm()->Set(
|
99
101
|
fresh.reg(),
|
100
102
|
Immediate(Smi::cast(*handle())->value()));
|
101
103
|
} else {
|
@@ -105,22 +107,20 @@ void Result::ToRegister(Register target) {
|
|
105
107
|
if (double_value == 0 && signbit(double_value)) {
|
106
108
|
// Negative zero must not be converted to an int32 unless
|
107
109
|
// the context allows it.
|
108
|
-
|
109
|
-
|
110
|
+
code_generator->unsafe_bailout_->Branch(equal);
|
111
|
+
code_generator->unsafe_bailout_->Branch(not_equal);
|
110
112
|
} else if (double_value == value) {
|
111
|
-
|
112
|
-
fresh.reg(), Immediate(value));
|
113
|
+
code_generator->masm()->Set(fresh.reg(), Immediate(value));
|
113
114
|
} else {
|
114
|
-
|
115
|
-
|
115
|
+
code_generator->unsafe_bailout_->Branch(equal);
|
116
|
+
code_generator->unsafe_bailout_->Branch(not_equal);
|
116
117
|
}
|
117
118
|
}
|
118
119
|
} else {
|
119
|
-
if (
|
120
|
-
|
120
|
+
if (code_generator->IsUnsafeSmi(handle())) {
|
121
|
+
code_generator->MoveUnsafeSmi(fresh.reg(), handle());
|
121
122
|
} else {
|
122
|
-
|
123
|
-
Immediate(handle()));
|
123
|
+
code_generator->masm()->Set(fresh.reg(), Immediate(handle()));
|
124
124
|
}
|
125
125
|
}
|
126
126
|
}
|
@@ -128,9 +128,9 @@ void Result::ToRegister(Register target) {
|
|
128
128
|
fresh.set_untagged_int32(is_untagged_int32());
|
129
129
|
*this = fresh;
|
130
130
|
} else if (is_register() && reg().is(target)) {
|
131
|
-
ASSERT(
|
132
|
-
|
133
|
-
ASSERT(
|
131
|
+
ASSERT(code_generator->has_valid_frame());
|
132
|
+
code_generator->frame()->Spill(target);
|
133
|
+
ASSERT(code_generator->allocator()->count(target) == 1);
|
134
134
|
}
|
135
135
|
ASSERT(is_register());
|
136
136
|
ASSERT(reg().is(target));
|
@@ -40,12 +40,12 @@ namespace internal {
|
|
40
40
|
|
41
41
|
|
42
42
|
typedef int (*regexp_matcher)(String*, int, const byte*,
|
43
|
-
const byte*, int*, Address, int);
|
43
|
+
const byte*, int*, Address, int, Isolate*);
|
44
44
|
|
45
45
|
// Call the generated regexp code directly. The code at the entry address should
|
46
|
-
// expect
|
47
|
-
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
|
48
|
-
(FUNCTION_CAST<regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6))
|
46
|
+
// expect eight int/pointer sized arguments and return an int.
|
47
|
+
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
|
48
|
+
(FUNCTION_CAST<regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7))
|
49
49
|
|
50
50
|
|
51
51
|
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
|
@@ -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:
|
@@ -39,14 +39,15 @@ namespace internal {
|
|
39
39
|
#define __ ACCESS_MASM(masm)
|
40
40
|
|
41
41
|
|
42
|
-
static void ProbeTable(
|
42
|
+
static void ProbeTable(Isolate* isolate,
|
43
|
+
MacroAssembler* masm,
|
43
44
|
Code::Flags flags,
|
44
45
|
StubCache::Table table,
|
45
46
|
Register name,
|
46
47
|
Register offset,
|
47
48
|
Register extra) {
|
48
|
-
ExternalReference key_offset(
|
49
|
-
ExternalReference value_offset(
|
49
|
+
ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
|
50
|
+
ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
|
50
51
|
|
51
52
|
Label miss;
|
52
53
|
|
@@ -113,8 +114,9 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
|
|
113
114
|
Register r0,
|
114
115
|
Register r1) {
|
115
116
|
ASSERT(name->IsSymbol());
|
116
|
-
|
117
|
-
__ IncrementCounter(
|
117
|
+
Counters* counters = masm->isolate()->counters();
|
118
|
+
__ IncrementCounter(counters->negative_lookups(), 1);
|
119
|
+
__ IncrementCounter(counters->negative_lookups_miss(), 1);
|
118
120
|
|
119
121
|
Label done;
|
120
122
|
__ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset));
|
@@ -137,7 +139,7 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
|
|
137
139
|
|
138
140
|
// Check that the properties array is a dictionary.
|
139
141
|
__ cmp(FieldOperand(properties, HeapObject::kMapOffset),
|
140
|
-
Immediate(
|
142
|
+
Immediate(masm->isolate()->factory()->hash_table_map()));
|
141
143
|
__ j(not_equal, miss_label);
|
142
144
|
|
143
145
|
// Compute the capacity mask.
|
@@ -177,7 +179,7 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
|
|
177
179
|
ASSERT_EQ(kSmiTagSize, 1);
|
178
180
|
__ mov(entity_name, Operand(properties, index, times_half_pointer_size,
|
179
181
|
kElementsStartOffset - kHeapObjectTag));
|
180
|
-
__ cmp(entity_name,
|
182
|
+
__ cmp(entity_name, masm->isolate()->factory()->undefined_value());
|
181
183
|
if (i != kProbes - 1) {
|
182
184
|
__ j(equal, &done, taken);
|
183
185
|
|
@@ -197,7 +199,7 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
|
|
197
199
|
}
|
198
200
|
|
199
201
|
__ bind(&done);
|
200
|
-
__ DecrementCounter(
|
202
|
+
__ DecrementCounter(counters->negative_lookups_miss(), 1);
|
201
203
|
}
|
202
204
|
|
203
205
|
|
@@ -208,6 +210,7 @@ void StubCache::GenerateProbe(MacroAssembler* masm,
|
|
208
210
|
Register scratch,
|
209
211
|
Register extra,
|
210
212
|
Register extra2) {
|
213
|
+
Isolate* isolate = Isolate::Current();
|
211
214
|
Label miss;
|
212
215
|
USE(extra2); // The register extra2 is not used on the ia32 platform.
|
213
216
|
|
@@ -240,7 +243,7 @@ void StubCache::GenerateProbe(MacroAssembler* masm,
|
|
240
243
|
__ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
|
241
244
|
|
242
245
|
// Probe the primary table.
|
243
|
-
ProbeTable(masm, flags, kPrimary, name, scratch, extra);
|
246
|
+
ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra);
|
244
247
|
|
245
248
|
// Primary miss: Compute hash for secondary probe.
|
246
249
|
__ mov(scratch, FieldOperand(name, String::kHashFieldOffset));
|
@@ -252,7 +255,7 @@ void StubCache::GenerateProbe(MacroAssembler* masm,
|
|
252
255
|
__ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize);
|
253
256
|
|
254
257
|
// Probe the secondary table.
|
255
|
-
ProbeTable(masm, flags, kSecondary, name, scratch, extra);
|
258
|
+
ProbeTable(isolate, masm, flags, kSecondary, name, scratch, extra);
|
256
259
|
|
257
260
|
// Cache miss: Fall-through and let caller handle the miss by
|
258
261
|
// entering the runtime system.
|
@@ -274,10 +277,11 @@ void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
|
|
274
277
|
MacroAssembler* masm, int index, Register prototype, Label* miss) {
|
275
278
|
// Check we're still in the same context.
|
276
279
|
__ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)),
|
277
|
-
|
280
|
+
masm->isolate()->global());
|
278
281
|
__ j(not_equal, miss);
|
279
282
|
// Get the global function with the given index.
|
280
|
-
JSFunction* function =
|
283
|
+
JSFunction* function =
|
284
|
+
JSFunction::cast(masm->isolate()->global_context()->get(index));
|
281
285
|
// Load its initial map. The global functions all have initial maps.
|
282
286
|
__ Set(prototype, Immediate(Handle<Map>(function->initial_map())));
|
283
287
|
// Load the prototype from the initial map.
|
@@ -395,7 +399,7 @@ static void PushInterceptorArguments(MacroAssembler* masm,
|
|
395
399
|
JSObject* holder_obj) {
|
396
400
|
__ push(name);
|
397
401
|
InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
|
398
|
-
ASSERT(!
|
402
|
+
ASSERT(!masm->isolate()->heap()->InNewSpace(interceptor));
|
399
403
|
Register scratch = name;
|
400
404
|
__ mov(scratch, Immediate(Handle<Object>(interceptor)));
|
401
405
|
__ push(scratch);
|
@@ -412,8 +416,9 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
|
|
412
416
|
JSObject* holder_obj) {
|
413
417
|
PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
|
414
418
|
__ CallExternalReference(
|
415
|
-
|
416
|
-
|
419
|
+
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
|
420
|
+
masm->isolate()),
|
421
|
+
5);
|
417
422
|
}
|
418
423
|
|
419
424
|
|
@@ -480,7 +485,7 @@ static MaybeObject* GenerateFastApiCall(MacroAssembler* masm,
|
|
480
485
|
__ mov(Operand(esp, 2 * kPointerSize), edi);
|
481
486
|
Object* call_data = optimization.api_call_info()->data();
|
482
487
|
Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
|
483
|
-
if (
|
488
|
+
if (masm->isolate()->heap()->InNewSpace(call_data)) {
|
484
489
|
__ mov(ecx, api_call_info_handle);
|
485
490
|
__ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
|
486
491
|
__ mov(Operand(esp, 3 * kPointerSize), ebx);
|
@@ -574,7 +579,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
|
574
579
|
name,
|
575
580
|
holder,
|
576
581
|
miss);
|
577
|
-
return
|
582
|
+
return masm->isolate()->heap()->undefined_value(); // Success.
|
578
583
|
}
|
579
584
|
}
|
580
585
|
|
@@ -610,10 +615,11 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
|
610
615
|
(depth2 != kInvalidProtoDepth);
|
611
616
|
}
|
612
617
|
|
613
|
-
|
618
|
+
Counters* counters = masm->isolate()->counters();
|
619
|
+
__ IncrementCounter(counters->call_const_interceptor(), 1);
|
614
620
|
|
615
621
|
if (can_do_fast_api_call) {
|
616
|
-
__ IncrementCounter(
|
622
|
+
__ IncrementCounter(counters->call_const_interceptor_fast_api(), 1);
|
617
623
|
ReserveSpaceForFastApiCall(masm, scratch1);
|
618
624
|
}
|
619
625
|
|
@@ -672,7 +678,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
|
672
678
|
FreeSpaceForFastApiCall(masm, scratch1);
|
673
679
|
}
|
674
680
|
|
675
|
-
return
|
681
|
+
return masm->isolate()->heap()->undefined_value(); // Success.
|
676
682
|
}
|
677
683
|
|
678
684
|
void CompileRegular(MacroAssembler* masm,
|
@@ -700,9 +706,9 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
|
700
706
|
interceptor_holder);
|
701
707
|
|
702
708
|
__ CallExternalReference(
|
703
|
-
|
704
|
-
|
705
|
-
|
709
|
+
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
|
710
|
+
masm->isolate()),
|
711
|
+
5);
|
706
712
|
|
707
713
|
// Restore the name_ register.
|
708
714
|
__ pop(name_);
|
@@ -728,7 +734,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
|
728
734
|
__ pop(receiver); // Restore the holder.
|
729
735
|
__ LeaveInternalFrame();
|
730
736
|
|
731
|
-
__ cmp(eax,
|
737
|
+
__ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel());
|
732
738
|
__ j(not_equal, interceptor_succeeded);
|
733
739
|
}
|
734
740
|
|
@@ -742,9 +748,9 @@ void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
|
|
742
748
|
ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
|
743
749
|
Code* code = NULL;
|
744
750
|
if (kind == Code::LOAD_IC) {
|
745
|
-
code =
|
751
|
+
code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
|
746
752
|
} else {
|
747
|
-
code =
|
753
|
+
code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
|
748
754
|
}
|
749
755
|
|
750
756
|
Handle<Code> ic(code);
|
@@ -790,7 +796,10 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
|
|
790
796
|
__ push(eax);
|
791
797
|
__ push(scratch);
|
792
798
|
__ TailCallExternalReference(
|
793
|
-
ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)
|
799
|
+
ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
|
800
|
+
masm->isolate()),
|
801
|
+
3,
|
802
|
+
1);
|
794
803
|
return;
|
795
804
|
}
|
796
805
|
|
@@ -851,10 +860,10 @@ MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell(
|
|
851
860
|
if (Serializer::enabled()) {
|
852
861
|
__ mov(scratch, Immediate(Handle<Object>(cell)));
|
853
862
|
__ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
|
854
|
-
Immediate(
|
863
|
+
Immediate(masm->isolate()->factory()->the_hole_value()));
|
855
864
|
} else {
|
856
865
|
__ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)),
|
857
|
-
Immediate(
|
866
|
+
Immediate(masm->isolate()->factory()->the_hole_value()));
|
858
867
|
}
|
859
868
|
__ j(not_equal, miss, not_taken);
|
860
869
|
return cell;
|
@@ -906,6 +915,7 @@ Register StubCompiler::CheckPrototypes(JSObject* object,
|
|
906
915
|
ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
|
907
916
|
ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
|
908
917
|
&& !scratch2.is(scratch1));
|
918
|
+
|
909
919
|
// Keep track of the current object in register reg.
|
910
920
|
Register reg = object_reg;
|
911
921
|
JSObject* current = object;
|
@@ -930,7 +940,7 @@ Register StubCompiler::CheckPrototypes(JSObject* object,
|
|
930
940
|
!current->IsJSGlobalObject() &&
|
931
941
|
!current->IsJSGlobalProxy()) {
|
932
942
|
if (!name->IsSymbol()) {
|
933
|
-
MaybeObject* maybe_lookup_result =
|
943
|
+
MaybeObject* maybe_lookup_result = heap()->LookupSymbol(name);
|
934
944
|
Object* lookup_result = NULL; // Initialization to please compiler.
|
935
945
|
if (!maybe_lookup_result->ToObject(&lookup_result)) {
|
936
946
|
set_failure(Failure::cast(maybe_lookup_result));
|
@@ -950,7 +960,7 @@ Register StubCompiler::CheckPrototypes(JSObject* object,
|
|
950
960
|
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
951
961
|
reg = holder_reg; // from now the object is in holder_reg
|
952
962
|
__ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
|
953
|
-
} else if (
|
963
|
+
} else if (heap()->InNewSpace(prototype)) {
|
954
964
|
// Get the map of the current object.
|
955
965
|
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
956
966
|
__ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map())));
|
@@ -997,7 +1007,7 @@ Register StubCompiler::CheckPrototypes(JSObject* object,
|
|
997
1007
|
ASSERT(current == holder);
|
998
1008
|
|
999
1009
|
// Log the check depth.
|
1000
|
-
LOG(IntEvent("check-maps-depth", depth + 1));
|
1010
|
+
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
|
1001
1011
|
|
1002
1012
|
// Check the holder map.
|
1003
1013
|
__ cmp(FieldOperand(reg, HeapObject::kMapOffset),
|
@@ -1080,7 +1090,7 @@ MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
|
|
1080
1090
|
ASSERT(!scratch2.is(reg));
|
1081
1091
|
__ push(reg); // holder
|
1082
1092
|
// Push data from AccessorInfo.
|
1083
|
-
if (
|
1093
|
+
if (isolate()->heap()->InNewSpace(callback_handle->data())) {
|
1084
1094
|
__ mov(scratch1, Immediate(callback_handle));
|
1085
1095
|
__ push(FieldOperand(scratch1, AccessorInfo::kDataOffset));
|
1086
1096
|
} else {
|
@@ -1204,7 +1214,7 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object,
|
|
1204
1214
|
// Check if interceptor provided a value for property. If it's
|
1205
1215
|
// the case, return immediately.
|
1206
1216
|
Label interceptor_failed;
|
1207
|
-
__ cmp(eax,
|
1217
|
+
__ cmp(eax, factory()->no_interceptor_result_sentinel());
|
1208
1218
|
__ j(equal, &interceptor_failed);
|
1209
1219
|
__ LeaveInternalFrame();
|
1210
1220
|
__ ret(0);
|
@@ -1259,7 +1269,8 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object,
|
|
1259
1269
|
__ push(scratch2); // restore return address
|
1260
1270
|
|
1261
1271
|
ExternalReference ref =
|
1262
|
-
ExternalReference(IC_Utility(IC::kLoadCallbackProperty)
|
1272
|
+
ExternalReference(IC_Utility(IC::kLoadCallbackProperty),
|
1273
|
+
masm()->isolate());
|
1263
1274
|
__ TailCallExternalReference(ref, 5, 1);
|
1264
1275
|
}
|
1265
1276
|
} else { // !compile_followup_inline
|
@@ -1273,8 +1284,9 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object,
|
|
1273
1284
|
name_reg, interceptor_holder);
|
1274
1285
|
__ push(scratch2); // restore old return address
|
1275
1286
|
|
1276
|
-
ExternalReference ref =
|
1277
|
-
IC_Utility(IC::kLoadPropertyWithInterceptorForLoad)
|
1287
|
+
ExternalReference ref =
|
1288
|
+
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
|
1289
|
+
isolate());
|
1278
1290
|
__ TailCallExternalReference(ref, 5, 1);
|
1279
1291
|
}
|
1280
1292
|
}
|
@@ -1325,7 +1337,7 @@ void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell,
|
|
1325
1337
|
}
|
1326
1338
|
|
1327
1339
|
// Check that the cell contains the same function.
|
1328
|
-
if (
|
1340
|
+
if (isolate()->heap()->InNewSpace(function)) {
|
1329
1341
|
// We can't embed a pointer to a function in new space so we have
|
1330
1342
|
// to verify that the shared function info is unchanged. This has
|
1331
1343
|
// the nice side effect that multiple closures based on the same
|
@@ -1348,8 +1360,9 @@ void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell,
|
|
1348
1360
|
|
1349
1361
|
|
1350
1362
|
MaybeObject* CallStubCompiler::GenerateMissBranch() {
|
1351
|
-
MaybeObject* maybe_obj =
|
1352
|
-
|
1363
|
+
MaybeObject* maybe_obj =
|
1364
|
+
isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
|
1365
|
+
kind_);
|
1353
1366
|
Object* obj;
|
1354
1367
|
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
1355
1368
|
__ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
|
@@ -1405,10 +1418,8 @@ MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField(
|
|
1405
1418
|
|
1406
1419
|
// Handle call cache miss.
|
1407
1420
|
__ bind(&miss);
|
1408
|
-
|
1409
|
-
|
1410
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
1411
|
-
}
|
1421
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
1422
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
1412
1423
|
|
1413
1424
|
// Return the generated code.
|
1414
1425
|
return GetCode(FIELD, name);
|
@@ -1429,7 +1440,9 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
|
|
1429
1440
|
// -----------------------------------
|
1430
1441
|
|
1431
1442
|
// If object is not an array, bail out to regular call.
|
1432
|
-
if (!object->IsJSArray() || cell != NULL)
|
1443
|
+
if (!object->IsJSArray() || cell != NULL) {
|
1444
|
+
return isolate()->heap()->undefined_value();
|
1445
|
+
}
|
1433
1446
|
|
1434
1447
|
Label miss;
|
1435
1448
|
|
@@ -1459,7 +1472,7 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
|
|
1459
1472
|
|
1460
1473
|
// Check that the elements are in fast mode and writable.
|
1461
1474
|
__ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
|
1462
|
-
Immediate(
|
1475
|
+
Immediate(factory()->fixed_array_map()));
|
1463
1476
|
__ j(not_equal, &call_builtin);
|
1464
1477
|
|
1465
1478
|
if (argc == 1) { // Otherwise fall through to call builtin.
|
@@ -1508,9 +1521,9 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
|
|
1508
1521
|
}
|
1509
1522
|
|
1510
1523
|
ExternalReference new_space_allocation_top =
|
1511
|
-
ExternalReference::new_space_allocation_top_address();
|
1524
|
+
ExternalReference::new_space_allocation_top_address(isolate());
|
1512
1525
|
ExternalReference new_space_allocation_limit =
|
1513
|
-
ExternalReference::new_space_allocation_limit_address();
|
1526
|
+
ExternalReference::new_space_allocation_limit_address(isolate());
|
1514
1527
|
|
1515
1528
|
const int kAllocationDelta = 4;
|
1516
1529
|
// Load top.
|
@@ -1535,7 +1548,7 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
|
|
1535
1548
|
// ... and fill the rest with holes.
|
1536
1549
|
for (int i = 1; i < kAllocationDelta; i++) {
|
1537
1550
|
__ mov(Operand(edx, i * kPointerSize),
|
1538
|
-
Immediate(
|
1551
|
+
Immediate(factory()->the_hole_value()));
|
1539
1552
|
}
|
1540
1553
|
|
1541
1554
|
// Restore receiver to edx as finish sequence assumes it's here.
|
@@ -1551,16 +1564,15 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
|
|
1551
1564
|
}
|
1552
1565
|
|
1553
1566
|
__ bind(&call_builtin);
|
1554
|
-
__ TailCallExternalReference(
|
1555
|
-
|
1556
|
-
|
1567
|
+
__ TailCallExternalReference(
|
1568
|
+
ExternalReference(Builtins::c_ArrayPush, isolate()),
|
1569
|
+
argc + 1,
|
1570
|
+
1);
|
1557
1571
|
}
|
1558
1572
|
|
1559
1573
|
__ bind(&miss);
|
1560
|
-
|
1561
|
-
|
1562
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
1563
|
-
}
|
1574
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
1575
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
1564
1576
|
|
1565
1577
|
// Return the generated code.
|
1566
1578
|
return GetCode(function);
|
@@ -1581,7 +1593,9 @@ MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
|
|
1581
1593
|
// -----------------------------------
|
1582
1594
|
|
1583
1595
|
// If object is not an array, bail out to regular call.
|
1584
|
-
if (!object->IsJSArray() || cell != NULL)
|
1596
|
+
if (!object->IsJSArray() || cell != NULL) {
|
1597
|
+
return heap()->undefined_value();
|
1598
|
+
}
|
1585
1599
|
|
1586
1600
|
Label miss, return_undefined, call_builtin;
|
1587
1601
|
|
@@ -1603,7 +1617,7 @@ MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
|
|
1603
1617
|
|
1604
1618
|
// Check that the elements are in fast mode and writable.
|
1605
1619
|
__ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
|
1606
|
-
Immediate(
|
1620
|
+
Immediate(factory()->fixed_array_map()));
|
1607
1621
|
__ j(not_equal, &call_builtin);
|
1608
1622
|
|
1609
1623
|
// Get the array's length into ecx and calculate new length.
|
@@ -1617,7 +1631,7 @@ MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
|
|
1617
1631
|
__ mov(eax, FieldOperand(ebx,
|
1618
1632
|
ecx, times_half_pointer_size,
|
1619
1633
|
FixedArray::kHeaderSize));
|
1620
|
-
__ cmp(Operand(eax), Immediate(
|
1634
|
+
__ cmp(Operand(eax), Immediate(factory()->the_hole_value()));
|
1621
1635
|
__ j(equal, &call_builtin);
|
1622
1636
|
|
1623
1637
|
// Set the array's length.
|
@@ -1627,23 +1641,22 @@ MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
|
|
1627
1641
|
__ mov(FieldOperand(ebx,
|
1628
1642
|
ecx, times_half_pointer_size,
|
1629
1643
|
FixedArray::kHeaderSize),
|
1630
|
-
Immediate(
|
1644
|
+
Immediate(factory()->the_hole_value()));
|
1631
1645
|
__ ret((argc + 1) * kPointerSize);
|
1632
1646
|
|
1633
1647
|
__ bind(&return_undefined);
|
1634
|
-
__ mov(eax, Immediate(
|
1648
|
+
__ mov(eax, Immediate(factory()->undefined_value()));
|
1635
1649
|
__ ret((argc + 1) * kPointerSize);
|
1636
1650
|
|
1637
1651
|
__ bind(&call_builtin);
|
1638
|
-
__ TailCallExternalReference(
|
1639
|
-
|
1640
|
-
|
1652
|
+
__ TailCallExternalReference(
|
1653
|
+
ExternalReference(Builtins::c_ArrayPop, isolate()),
|
1654
|
+
argc + 1,
|
1655
|
+
1);
|
1641
1656
|
|
1642
1657
|
__ bind(&miss);
|
1643
|
-
|
1644
|
-
|
1645
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
1646
|
-
}
|
1658
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
1659
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
1647
1660
|
|
1648
1661
|
// Return the generated code.
|
1649
1662
|
return GetCode(function);
|
@@ -1665,7 +1678,9 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
|
|
1665
1678
|
// -----------------------------------
|
1666
1679
|
|
1667
1680
|
// If object is not a string, bail out to regular call.
|
1668
|
-
if (!object->IsString() || cell != NULL)
|
1681
|
+
if (!object->IsString() || cell != NULL) {
|
1682
|
+
return isolate()->heap()->undefined_value();
|
1683
|
+
}
|
1669
1684
|
|
1670
1685
|
const int argc = arguments().immediate();
|
1671
1686
|
|
@@ -1697,7 +1712,7 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
|
|
1697
1712
|
if (argc > 0) {
|
1698
1713
|
__ mov(index, Operand(esp, (argc - 0) * kPointerSize));
|
1699
1714
|
} else {
|
1700
|
-
__ Set(index, Immediate(
|
1715
|
+
__ Set(index, Immediate(factory()->undefined_value()));
|
1701
1716
|
}
|
1702
1717
|
|
1703
1718
|
StringCharCodeAtGenerator char_code_at_generator(receiver,
|
@@ -1716,7 +1731,7 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
|
|
1716
1731
|
|
1717
1732
|
if (index_out_of_range.is_linked()) {
|
1718
1733
|
__ bind(&index_out_of_range);
|
1719
|
-
__ Set(eax, Immediate(
|
1734
|
+
__ Set(eax, Immediate(factory()->nan_value()));
|
1720
1735
|
__ ret((argc + 1) * kPointerSize);
|
1721
1736
|
}
|
1722
1737
|
|
@@ -1724,10 +1739,8 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
|
|
1724
1739
|
// Restore function name in ecx.
|
1725
1740
|
__ Set(ecx, Immediate(Handle<String>(name)));
|
1726
1741
|
__ bind(&name_miss);
|
1727
|
-
|
1728
|
-
|
1729
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
1730
|
-
}
|
1742
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
1743
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
1731
1744
|
|
1732
1745
|
// Return the generated code.
|
1733
1746
|
return GetCode(function);
|
@@ -1749,7 +1762,9 @@ MaybeObject* CallStubCompiler::CompileStringCharAtCall(
|
|
1749
1762
|
// -----------------------------------
|
1750
1763
|
|
1751
1764
|
// If object is not a string, bail out to regular call.
|
1752
|
-
if (!object->IsString() || cell != NULL)
|
1765
|
+
if (!object->IsString() || cell != NULL) {
|
1766
|
+
return heap()->undefined_value();
|
1767
|
+
}
|
1753
1768
|
|
1754
1769
|
const int argc = arguments().immediate();
|
1755
1770
|
|
@@ -1782,7 +1797,7 @@ MaybeObject* CallStubCompiler::CompileStringCharAtCall(
|
|
1782
1797
|
if (argc > 0) {
|
1783
1798
|
__ mov(index, Operand(esp, (argc - 0) * kPointerSize));
|
1784
1799
|
} else {
|
1785
|
-
__ Set(index, Immediate(
|
1800
|
+
__ Set(index, Immediate(factory()->undefined_value()));
|
1786
1801
|
}
|
1787
1802
|
|
1788
1803
|
StringCharAtGenerator char_at_generator(receiver,
|
@@ -1802,7 +1817,7 @@ MaybeObject* CallStubCompiler::CompileStringCharAtCall(
|
|
1802
1817
|
|
1803
1818
|
if (index_out_of_range.is_linked()) {
|
1804
1819
|
__ bind(&index_out_of_range);
|
1805
|
-
__ Set(eax, Immediate(
|
1820
|
+
__ Set(eax, Immediate(factory()->empty_string()));
|
1806
1821
|
__ ret((argc + 1) * kPointerSize);
|
1807
1822
|
}
|
1808
1823
|
|
@@ -1810,10 +1825,8 @@ MaybeObject* CallStubCompiler::CompileStringCharAtCall(
|
|
1810
1825
|
// Restore function name in ecx.
|
1811
1826
|
__ Set(ecx, Immediate(Handle<String>(name)));
|
1812
1827
|
__ bind(&name_miss);
|
1813
|
-
|
1814
|
-
|
1815
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
1816
|
-
}
|
1828
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
1829
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
1817
1830
|
|
1818
1831
|
// Return the generated code.
|
1819
1832
|
return GetCode(function);
|
@@ -1838,7 +1851,9 @@ MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
|
|
1838
1851
|
|
1839
1852
|
// If the object is not a JSObject or we got an unexpected number of
|
1840
1853
|
// arguments, bail out to the regular call.
|
1841
|
-
if (!object->IsJSObject() || argc != 1)
|
1854
|
+
if (!object->IsJSObject() || argc != 1) {
|
1855
|
+
return isolate()->heap()->undefined_value();
|
1856
|
+
}
|
1842
1857
|
|
1843
1858
|
Label miss;
|
1844
1859
|
GenerateNameCheck(name, &miss);
|
@@ -1885,10 +1900,8 @@ MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
|
|
1885
1900
|
|
1886
1901
|
__ bind(&miss);
|
1887
1902
|
// ecx: function name.
|
1888
|
-
|
1889
|
-
|
1890
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
1891
|
-
}
|
1903
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
1904
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
1892
1905
|
|
1893
1906
|
// Return the generated code.
|
1894
1907
|
return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
|
@@ -1908,14 +1921,19 @@ MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
|
|
1908
1921
|
// -- esp[(argc + 1) * 4] : receiver
|
1909
1922
|
// -----------------------------------
|
1910
1923
|
|
1911
|
-
if (!CpuFeatures::IsSupported(SSE2))
|
1924
|
+
if (!CpuFeatures::IsSupported(SSE2)) {
|
1925
|
+
return isolate()->heap()->undefined_value();
|
1926
|
+
}
|
1927
|
+
|
1912
1928
|
CpuFeatures::Scope use_sse2(SSE2);
|
1913
1929
|
|
1914
1930
|
const int argc = arguments().immediate();
|
1915
1931
|
|
1916
1932
|
// If the object is not a JSObject or we got an unexpected number of
|
1917
1933
|
// arguments, bail out to the regular call.
|
1918
|
-
if (!object->IsJSObject() || argc != 1)
|
1934
|
+
if (!object->IsJSObject() || argc != 1) {
|
1935
|
+
return isolate()->heap()->undefined_value();
|
1936
|
+
}
|
1919
1937
|
|
1920
1938
|
Label miss;
|
1921
1939
|
GenerateNameCheck(name, &miss);
|
@@ -1946,7 +1964,7 @@ MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
|
|
1946
1964
|
|
1947
1965
|
// Check if the argument is a heap number and load its value into xmm0.
|
1948
1966
|
Label slow;
|
1949
|
-
__ CheckMap(eax,
|
1967
|
+
__ CheckMap(eax, factory()->heap_number_map(), &slow, true);
|
1950
1968
|
__ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
|
1951
1969
|
|
1952
1970
|
// Check if the argument is strictly positive. Note this also
|
@@ -2012,10 +2030,8 @@ MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
|
|
2012
2030
|
|
2013
2031
|
__ bind(&miss);
|
2014
2032
|
// ecx: function name.
|
2015
|
-
|
2016
|
-
|
2017
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
2018
|
-
}
|
2033
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
2034
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
2019
2035
|
|
2020
2036
|
// Return the generated code.
|
2021
2037
|
return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
|
@@ -2039,7 +2055,9 @@ MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object,
|
|
2039
2055
|
|
2040
2056
|
// If the object is not a JSObject or we got an unexpected number of
|
2041
2057
|
// arguments, bail out to the regular call.
|
2042
|
-
if (!object->IsJSObject() || argc != 1)
|
2058
|
+
if (!object->IsJSObject() || argc != 1) {
|
2059
|
+
return isolate()->heap()->undefined_value();
|
2060
|
+
}
|
2043
2061
|
|
2044
2062
|
Label miss;
|
2045
2063
|
GenerateNameCheck(name, &miss);
|
@@ -2090,7 +2108,7 @@ MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object,
|
|
2090
2108
|
// Check if the argument is a heap number and load its exponent and
|
2091
2109
|
// sign into ebx.
|
2092
2110
|
__ bind(¬_smi);
|
2093
|
-
__ CheckMap(eax,
|
2111
|
+
__ CheckMap(eax, factory()->heap_number_map(), &slow, true);
|
2094
2112
|
__ mov(ebx, FieldOperand(eax, HeapNumber::kExponentOffset));
|
2095
2113
|
|
2096
2114
|
// Check the sign of the argument. If the argument is positive,
|
@@ -2117,16 +2135,75 @@ MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object,
|
|
2117
2135
|
|
2118
2136
|
__ bind(&miss);
|
2119
2137
|
// ecx: function name.
|
2120
|
-
|
2121
|
-
|
2122
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
2123
|
-
}
|
2138
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
2139
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
2124
2140
|
|
2125
2141
|
// Return the generated code.
|
2126
2142
|
return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
|
2127
2143
|
}
|
2128
2144
|
|
2129
2145
|
|
2146
|
+
MaybeObject* CallStubCompiler::CompileFastApiCall(
|
2147
|
+
const CallOptimization& optimization,
|
2148
|
+
Object* object,
|
2149
|
+
JSObject* holder,
|
2150
|
+
JSGlobalPropertyCell* cell,
|
2151
|
+
JSFunction* function,
|
2152
|
+
String* name) {
|
2153
|
+
ASSERT(optimization.is_simple_api_call());
|
2154
|
+
// Bail out if object is a global object as we don't want to
|
2155
|
+
// repatch it to global receiver.
|
2156
|
+
if (object->IsGlobalObject()) return heap()->undefined_value();
|
2157
|
+
if (cell != NULL) return heap()->undefined_value();
|
2158
|
+
int depth = optimization.GetPrototypeDepthOfExpectedType(
|
2159
|
+
JSObject::cast(object), holder);
|
2160
|
+
if (depth == kInvalidProtoDepth) return heap()->undefined_value();
|
2161
|
+
|
2162
|
+
Label miss, miss_before_stack_reserved;
|
2163
|
+
|
2164
|
+
GenerateNameCheck(name, &miss_before_stack_reserved);
|
2165
|
+
|
2166
|
+
// Get the receiver from the stack.
|
2167
|
+
const int argc = arguments().immediate();
|
2168
|
+
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
|
2169
|
+
|
2170
|
+
// Check that the receiver isn't a smi.
|
2171
|
+
__ test(edx, Immediate(kSmiTagMask));
|
2172
|
+
__ j(zero, &miss_before_stack_reserved, not_taken);
|
2173
|
+
|
2174
|
+
Counters* counters = isolate()->counters();
|
2175
|
+
__ IncrementCounter(counters->call_const(), 1);
|
2176
|
+
__ IncrementCounter(counters->call_const_fast_api(), 1);
|
2177
|
+
|
2178
|
+
// Allocate space for v8::Arguments implicit values. Must be initialized
|
2179
|
+
// before calling any runtime function.
|
2180
|
+
__ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
|
2181
|
+
|
2182
|
+
// Check that the maps haven't changed and find a Holder as a side effect.
|
2183
|
+
CheckPrototypes(JSObject::cast(object), edx, holder,
|
2184
|
+
ebx, eax, edi, name, depth, &miss);
|
2185
|
+
|
2186
|
+
// Move the return address on top of the stack.
|
2187
|
+
__ mov(eax, Operand(esp, 3 * kPointerSize));
|
2188
|
+
__ mov(Operand(esp, 0 * kPointerSize), eax);
|
2189
|
+
|
2190
|
+
// esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
|
2191
|
+
// duplicate of return address and will be overwritten.
|
2192
|
+
MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
|
2193
|
+
if (result->IsFailure()) return result;
|
2194
|
+
|
2195
|
+
__ bind(&miss);
|
2196
|
+
__ add(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
|
2197
|
+
|
2198
|
+
__ bind(&miss_before_stack_reserved);
|
2199
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
2200
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
2201
|
+
|
2202
|
+
// Return the generated code.
|
2203
|
+
return GetCode(function);
|
2204
|
+
}
|
2205
|
+
|
2206
|
+
|
2130
2207
|
MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
|
2131
2208
|
JSObject* holder,
|
2132
2209
|
JSFunction* function,
|
@@ -2140,20 +2217,18 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
|
|
2140
2217
|
// -- esp[(argc + 1) * 4] : receiver
|
2141
2218
|
// -----------------------------------
|
2142
2219
|
|
2143
|
-
|
2144
|
-
if (function_info->HasBuiltinFunctionId()) {
|
2145
|
-
BuiltinFunctionId id = function_info->builtin_function_id();
|
2220
|
+
if (HasCustomCallGenerator(function)) {
|
2146
2221
|
MaybeObject* maybe_result = CompileCustomCall(
|
2147
|
-
|
2222
|
+
object, holder, NULL, function, name);
|
2148
2223
|
Object* result;
|
2149
2224
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
2150
2225
|
// undefined means bail out to regular compiler.
|
2151
2226
|
if (!result->IsUndefined()) return result;
|
2152
2227
|
}
|
2153
2228
|
|
2154
|
-
Label
|
2229
|
+
Label miss;
|
2155
2230
|
|
2156
|
-
GenerateNameCheck(name, &
|
2231
|
+
GenerateNameCheck(name, &miss);
|
2157
2232
|
|
2158
2233
|
// Get the receiver from the stack.
|
2159
2234
|
const int argc = arguments().immediate();
|
@@ -2162,42 +2237,25 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
|
|
2162
2237
|
// Check that the receiver isn't a smi.
|
2163
2238
|
if (check != NUMBER_CHECK) {
|
2164
2239
|
__ test(edx, Immediate(kSmiTagMask));
|
2165
|
-
__ j(zero, &
|
2240
|
+
__ j(zero, &miss, not_taken);
|
2166
2241
|
}
|
2167
2242
|
|
2168
2243
|
// Make sure that it's okay not to patch the on stack receiver
|
2169
2244
|
// unless we're doing a receiver map check.
|
2170
2245
|
ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
|
2171
2246
|
|
2172
|
-
|
2173
|
-
int depth = kInvalidProtoDepth;
|
2174
|
-
Label miss;
|
2175
|
-
|
2247
|
+
SharedFunctionInfo* function_info = function->shared();
|
2176
2248
|
switch (check) {
|
2177
2249
|
case RECEIVER_MAP_CHECK:
|
2178
|
-
__ IncrementCounter(
|
2179
|
-
|
2180
|
-
if (optimization.is_simple_api_call() && !object->IsGlobalObject()) {
|
2181
|
-
depth = optimization.GetPrototypeDepthOfExpectedType(
|
2182
|
-
JSObject::cast(object), holder);
|
2183
|
-
}
|
2184
|
-
|
2185
|
-
if (depth != kInvalidProtoDepth) {
|
2186
|
-
__ IncrementCounter(&Counters::call_const_fast_api, 1);
|
2187
|
-
|
2188
|
-
// Allocate space for v8::Arguments implicit values. Must be initialized
|
2189
|
-
// before to call any runtime function.
|
2190
|
-
__ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
|
2191
|
-
}
|
2250
|
+
__ IncrementCounter(isolate()->counters()->call_const(), 1);
|
2192
2251
|
|
2193
2252
|
// Check that the maps haven't changed.
|
2194
2253
|
CheckPrototypes(JSObject::cast(object), edx, holder,
|
2195
|
-
ebx, eax, edi, name,
|
2254
|
+
ebx, eax, edi, name, &miss);
|
2196
2255
|
|
2197
2256
|
// Patch the receiver on the stack with the global proxy if
|
2198
2257
|
// necessary.
|
2199
2258
|
if (object->IsGlobalObject()) {
|
2200
|
-
ASSERT(depth == kInvalidProtoDepth);
|
2201
2259
|
__ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
|
2202
2260
|
__ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
|
2203
2261
|
}
|
@@ -2250,9 +2308,9 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
|
|
2250
2308
|
} else {
|
2251
2309
|
Label fast;
|
2252
2310
|
// Check that the object is a boolean.
|
2253
|
-
__ cmp(edx,
|
2311
|
+
__ cmp(edx, factory()->true_value());
|
2254
2312
|
__ j(equal, &fast, taken);
|
2255
|
-
__ cmp(edx,
|
2313
|
+
__ cmp(edx, factory()->false_value());
|
2256
2314
|
__ j(not_equal, &miss, not_taken);
|
2257
2315
|
__ bind(&fast);
|
2258
2316
|
// Check that the maps starting from the prototype haven't changed.
|
@@ -2268,29 +2326,12 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
|
|
2268
2326
|
UNREACHABLE();
|
2269
2327
|
}
|
2270
2328
|
|
2271
|
-
|
2272
|
-
// Move the return address on top of the stack.
|
2273
|
-
__ mov(eax, Operand(esp, 3 * kPointerSize));
|
2274
|
-
__ mov(Operand(esp, 0 * kPointerSize), eax);
|
2275
|
-
|
2276
|
-
// esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
|
2277
|
-
// duplicate of return address and will be overwritten.
|
2278
|
-
MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
|
2279
|
-
if (result->IsFailure()) return result;
|
2280
|
-
} else {
|
2281
|
-
__ InvokeFunction(function, arguments(), JUMP_FUNCTION);
|
2282
|
-
}
|
2329
|
+
__ InvokeFunction(function, arguments(), JUMP_FUNCTION);
|
2283
2330
|
|
2284
2331
|
// Handle call cache miss.
|
2285
2332
|
__ bind(&miss);
|
2286
|
-
|
2287
|
-
|
2288
|
-
}
|
2289
|
-
__ bind(&miss_in_smi_check);
|
2290
|
-
Object* obj;
|
2291
|
-
{ MaybeObject* maybe_obj = GenerateMissBranch();
|
2292
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
2293
|
-
}
|
2333
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
2334
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
2294
2335
|
|
2295
2336
|
// Return the generated code.
|
2296
2337
|
return GetCode(function);
|
@@ -2355,10 +2396,8 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
|
|
2355
2396
|
|
2356
2397
|
// Handle load cache miss.
|
2357
2398
|
__ bind(&miss);
|
2358
|
-
|
2359
|
-
|
2360
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
2361
|
-
}
|
2399
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
2400
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
2362
2401
|
|
2363
2402
|
// Return the generated code.
|
2364
2403
|
return GetCode(INTERCEPTOR, name);
|
@@ -2378,11 +2417,9 @@ MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
|
|
2378
2417
|
// -- esp[(argc + 1) * 4] : receiver
|
2379
2418
|
// -----------------------------------
|
2380
2419
|
|
2381
|
-
|
2382
|
-
if (function_info->HasBuiltinFunctionId()) {
|
2383
|
-
BuiltinFunctionId id = function_info->builtin_function_id();
|
2420
|
+
if (HasCustomCallGenerator(function)) {
|
2384
2421
|
MaybeObject* maybe_result = CompileCustomCall(
|
2385
|
-
|
2422
|
+
object, holder, cell, function, name);
|
2386
2423
|
Object* result;
|
2387
2424
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
2388
2425
|
// undefined means bail out to regular compiler.
|
@@ -2410,7 +2447,8 @@ MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
|
|
2410
2447
|
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
|
2411
2448
|
|
2412
2449
|
// Jump to the cached code (tail call).
|
2413
|
-
|
2450
|
+
Counters* counters = isolate()->counters();
|
2451
|
+
__ IncrementCounter(counters->call_global_inline(), 1);
|
2414
2452
|
ASSERT(function->is_compiled());
|
2415
2453
|
ParameterCount expected(function->shared()->formal_parameter_count());
|
2416
2454
|
if (V8::UseCrankshaft()) {
|
@@ -2427,11 +2465,9 @@ MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
|
|
2427
2465
|
|
2428
2466
|
// Handle call cache miss.
|
2429
2467
|
__ bind(&miss);
|
2430
|
-
__ IncrementCounter(
|
2431
|
-
|
2432
|
-
|
2433
|
-
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
2434
|
-
}
|
2468
|
+
__ IncrementCounter(counters->call_global_inline_miss(), 1);
|
2469
|
+
MaybeObject* maybe_result = GenerateMissBranch();
|
2470
|
+
if (maybe_result->IsFailure()) return maybe_result;
|
2435
2471
|
|
2436
2472
|
// Return the generated code.
|
2437
2473
|
return GetCode(NORMAL, name);
|
@@ -2461,7 +2497,7 @@ MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object,
|
|
2461
2497
|
// Handle store cache miss.
|
2462
2498
|
__ bind(&miss);
|
2463
2499
|
__ mov(ecx, Immediate(Handle<String>(name))); // restore name
|
2464
|
-
Handle<Code> ic(
|
2500
|
+
Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
|
2465
2501
|
__ jmp(ic, RelocInfo::CODE_TARGET);
|
2466
2502
|
|
2467
2503
|
// Return the generated code.
|
@@ -2507,12 +2543,12 @@ MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object,
|
|
2507
2543
|
|
2508
2544
|
// Do tail-call to the runtime system.
|
2509
2545
|
ExternalReference store_callback_property =
|
2510
|
-
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
|
2546
|
+
ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
|
2511
2547
|
__ TailCallExternalReference(store_callback_property, 4, 1);
|
2512
2548
|
|
2513
2549
|
// Handle store cache miss.
|
2514
2550
|
__ bind(&miss);
|
2515
|
-
Handle<Code> ic(
|
2551
|
+
Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
|
2516
2552
|
__ jmp(ic, RelocInfo::CODE_TARGET);
|
2517
2553
|
|
2518
2554
|
// Return the generated code.
|
@@ -2552,16 +2588,17 @@ MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
|
|
2552
2588
|
__ push(edx); // receiver
|
2553
2589
|
__ push(ecx); // name
|
2554
2590
|
__ push(eax); // value
|
2591
|
+
__ push(Immediate(Smi::FromInt(strict_mode_)));
|
2555
2592
|
__ push(ebx); // restore return address
|
2556
2593
|
|
2557
2594
|
// Do tail-call to the runtime system.
|
2558
2595
|
ExternalReference store_ic_property =
|
2559
|
-
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
|
2560
|
-
__ TailCallExternalReference(store_ic_property,
|
2596
|
+
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
|
2597
|
+
__ TailCallExternalReference(store_ic_property, 4, 1);
|
2561
2598
|
|
2562
2599
|
// Handle store cache miss.
|
2563
2600
|
__ bind(&miss);
|
2564
|
-
Handle<Code> ic(
|
2601
|
+
Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
|
2565
2602
|
__ jmp(ic, RelocInfo::CODE_TARGET);
|
2566
2603
|
|
2567
2604
|
// Return the generated code.
|
@@ -2597,20 +2634,21 @@ MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
|
|
2597
2634
|
// cell could have been deleted and reintroducing the global needs
|
2598
2635
|
// to update the property details in the property dictionary of the
|
2599
2636
|
// global object. We bail out to the runtime system to do that.
|
2600
|
-
__ cmp(cell_operand,
|
2637
|
+
__ cmp(cell_operand, factory()->the_hole_value());
|
2601
2638
|
__ j(equal, &miss);
|
2602
2639
|
|
2603
2640
|
// Store the value in the cell.
|
2604
2641
|
__ mov(cell_operand, eax);
|
2605
2642
|
|
2606
2643
|
// Return the value (register eax).
|
2607
|
-
|
2644
|
+
Counters* counters = isolate()->counters();
|
2645
|
+
__ IncrementCounter(counters->named_store_global_inline(), 1);
|
2608
2646
|
__ ret(0);
|
2609
2647
|
|
2610
2648
|
// Handle store cache miss.
|
2611
2649
|
__ bind(&miss);
|
2612
|
-
__ IncrementCounter(
|
2613
|
-
Handle<Code> ic(
|
2650
|
+
__ IncrementCounter(counters->named_store_global_inline_miss(), 1);
|
2651
|
+
Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
|
2614
2652
|
__ jmp(ic, RelocInfo::CODE_TARGET);
|
2615
2653
|
|
2616
2654
|
// Return the generated code.
|
@@ -2630,7 +2668,8 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
|
|
2630
2668
|
// -----------------------------------
|
2631
2669
|
Label miss;
|
2632
2670
|
|
2633
|
-
|
2671
|
+
Counters* counters = isolate()->counters();
|
2672
|
+
__ IncrementCounter(counters->keyed_store_field(), 1);
|
2634
2673
|
|
2635
2674
|
// Check that the name has not changed.
|
2636
2675
|
__ cmp(Operand(ecx), Immediate(Handle<String>(name)));
|
@@ -2646,8 +2685,8 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
|
|
2646
2685
|
|
2647
2686
|
// Handle store cache miss.
|
2648
2687
|
__ bind(&miss);
|
2649
|
-
__ DecrementCounter(
|
2650
|
-
Handle<Code> ic(
|
2688
|
+
__ DecrementCounter(counters->keyed_store_field(), 1);
|
2689
|
+
Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
|
2651
2690
|
__ jmp(ic, RelocInfo::CODE_TARGET);
|
2652
2691
|
|
2653
2692
|
// Return the generated code.
|
@@ -2681,7 +2720,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(
|
|
2681
2720
|
// Get the elements array and make sure it is a fast element array, not 'cow'.
|
2682
2721
|
__ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
|
2683
2722
|
__ cmp(FieldOperand(edi, HeapObject::kMapOffset),
|
2684
|
-
Immediate(
|
2723
|
+
Immediate(factory()->fixed_array_map()));
|
2685
2724
|
__ j(not_equal, &miss, not_taken);
|
2686
2725
|
|
2687
2726
|
// Check that the key is within bounds.
|
@@ -2704,43 +2743,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(
|
|
2704
2743
|
|
2705
2744
|
// Handle store cache miss.
|
2706
2745
|
__ bind(&miss);
|
2707
|
-
Handle<Code> ic(
|
2708
|
-
__ jmp(ic, RelocInfo::CODE_TARGET);
|
2709
|
-
|
2710
|
-
// Return the generated code.
|
2711
|
-
return GetCode(NORMAL, NULL);
|
2712
|
-
}
|
2713
|
-
|
2714
|
-
|
2715
|
-
MaybeObject* KeyedStoreStubCompiler::CompileStorePixelArray(
|
2716
|
-
JSObject* receiver) {
|
2717
|
-
// ----------- S t a t e -------------
|
2718
|
-
// -- eax : value
|
2719
|
-
// -- ecx : key
|
2720
|
-
// -- edx : receiver
|
2721
|
-
// -- esp[0] : return address
|
2722
|
-
// -----------------------------------
|
2723
|
-
Label miss;
|
2724
|
-
|
2725
|
-
// Check that the map matches.
|
2726
|
-
__ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false);
|
2727
|
-
|
2728
|
-
// Do the load.
|
2729
|
-
GenerateFastPixelArrayStore(masm(),
|
2730
|
-
edx,
|
2731
|
-
ecx,
|
2732
|
-
eax,
|
2733
|
-
edi,
|
2734
|
-
ebx,
|
2735
|
-
true,
|
2736
|
-
&miss,
|
2737
|
-
&miss,
|
2738
|
-
NULL,
|
2739
|
-
&miss);
|
2740
|
-
|
2741
|
-
// Handle store cache miss.
|
2742
|
-
__ bind(&miss);
|
2743
|
-
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss));
|
2746
|
+
Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
|
2744
2747
|
__ jmp(ic, RelocInfo::CODE_TARGET);
|
2745
2748
|
|
2746
2749
|
// Return the generated code.
|
@@ -2785,14 +2788,14 @@ MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
|
|
2785
2788
|
|
2786
2789
|
// Return undefined if maps of the full prototype chain are still the
|
2787
2790
|
// same and no global property with this name contains a value.
|
2788
|
-
__ mov(eax,
|
2791
|
+
__ mov(eax, isolate()->factory()->undefined_value());
|
2789
2792
|
__ ret(0);
|
2790
2793
|
|
2791
2794
|
__ bind(&miss);
|
2792
2795
|
GenerateLoadMiss(masm(), Code::LOAD_IC);
|
2793
2796
|
|
2794
2797
|
// Return the generated code.
|
2795
|
-
return GetCode(NONEXISTENT,
|
2798
|
+
return GetCode(NONEXISTENT, isolate()->heap()->empty_string());
|
2796
2799
|
}
|
2797
2800
|
|
2798
2801
|
|
@@ -2929,19 +2932,20 @@ MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object,
|
|
2929
2932
|
|
2930
2933
|
// Check for deleted property if property can actually be deleted.
|
2931
2934
|
if (!is_dont_delete) {
|
2932
|
-
__ cmp(ebx,
|
2935
|
+
__ cmp(ebx, factory()->the_hole_value());
|
2933
2936
|
__ j(equal, &miss, not_taken);
|
2934
2937
|
} else if (FLAG_debug_code) {
|
2935
|
-
__ cmp(ebx,
|
2938
|
+
__ cmp(ebx, factory()->the_hole_value());
|
2936
2939
|
__ Check(not_equal, "DontDelete cells can't contain the hole");
|
2937
2940
|
}
|
2938
2941
|
|
2939
|
-
|
2942
|
+
Counters* counters = isolate()->counters();
|
2943
|
+
__ IncrementCounter(counters->named_load_global_stub(), 1);
|
2940
2944
|
__ mov(eax, ebx);
|
2941
2945
|
__ ret(0);
|
2942
2946
|
|
2943
2947
|
__ bind(&miss);
|
2944
|
-
__ IncrementCounter(
|
2948
|
+
__ IncrementCounter(counters->named_load_global_stub_miss(), 1);
|
2945
2949
|
GenerateLoadMiss(masm(), Code::LOAD_IC);
|
2946
2950
|
|
2947
2951
|
// Return the generated code.
|
@@ -2960,7 +2964,8 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name,
|
|
2960
2964
|
// -----------------------------------
|
2961
2965
|
Label miss;
|
2962
2966
|
|
2963
|
-
|
2967
|
+
Counters* counters = isolate()->counters();
|
2968
|
+
__ IncrementCounter(counters->keyed_load_field(), 1);
|
2964
2969
|
|
2965
2970
|
// Check that the name has not changed.
|
2966
2971
|
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
|
@@ -2969,7 +2974,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name,
|
|
2969
2974
|
GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss);
|
2970
2975
|
|
2971
2976
|
__ bind(&miss);
|
2972
|
-
__ DecrementCounter(
|
2977
|
+
__ DecrementCounter(counters->keyed_load_field(), 1);
|
2973
2978
|
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
2974
2979
|
|
2975
2980
|
// Return the generated code.
|
@@ -2989,7 +2994,8 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
|
|
2989
2994
|
// -----------------------------------
|
2990
2995
|
Label miss;
|
2991
2996
|
|
2992
|
-
|
2997
|
+
Counters* counters = isolate()->counters();
|
2998
|
+
__ IncrementCounter(counters->keyed_load_callback(), 1);
|
2993
2999
|
|
2994
3000
|
// Check that the name has not changed.
|
2995
3001
|
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
|
@@ -3004,7 +3010,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
|
|
3004
3010
|
|
3005
3011
|
__ bind(&miss);
|
3006
3012
|
|
3007
|
-
__ DecrementCounter(
|
3013
|
+
__ DecrementCounter(counters->keyed_load_callback(), 1);
|
3008
3014
|
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
3009
3015
|
|
3010
3016
|
// Return the generated code.
|
@@ -3023,7 +3029,8 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name,
|
|
3023
3029
|
// -----------------------------------
|
3024
3030
|
Label miss;
|
3025
3031
|
|
3026
|
-
|
3032
|
+
Counters* counters = isolate()->counters();
|
3033
|
+
__ IncrementCounter(counters->keyed_load_constant_function(), 1);
|
3027
3034
|
|
3028
3035
|
// Check that the name has not changed.
|
3029
3036
|
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
|
@@ -3032,7 +3039,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name,
|
|
3032
3039
|
GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi,
|
3033
3040
|
value, name, &miss);
|
3034
3041
|
__ bind(&miss);
|
3035
|
-
__ DecrementCounter(
|
3042
|
+
__ DecrementCounter(counters->keyed_load_constant_function(), 1);
|
3036
3043
|
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
3037
3044
|
|
3038
3045
|
// Return the generated code.
|
@@ -3050,7 +3057,8 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
|
3050
3057
|
// -----------------------------------
|
3051
3058
|
Label miss;
|
3052
3059
|
|
3053
|
-
|
3060
|
+
Counters* counters = isolate()->counters();
|
3061
|
+
__ IncrementCounter(counters->keyed_load_interceptor(), 1);
|
3054
3062
|
|
3055
3063
|
// Check that the name has not changed.
|
3056
3064
|
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
|
@@ -3069,7 +3077,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
|
3069
3077
|
name,
|
3070
3078
|
&miss);
|
3071
3079
|
__ bind(&miss);
|
3072
|
-
__ DecrementCounter(
|
3080
|
+
__ DecrementCounter(counters->keyed_load_interceptor(), 1);
|
3073
3081
|
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
3074
3082
|
|
3075
3083
|
// Return the generated code.
|
@@ -3085,7 +3093,8 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
|
|
3085
3093
|
// -----------------------------------
|
3086
3094
|
Label miss;
|
3087
3095
|
|
3088
|
-
|
3096
|
+
Counters* counters = isolate()->counters();
|
3097
|
+
__ IncrementCounter(counters->keyed_load_array_length(), 1);
|
3089
3098
|
|
3090
3099
|
// Check that the name has not changed.
|
3091
3100
|
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
|
@@ -3093,7 +3102,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
|
|
3093
3102
|
|
3094
3103
|
GenerateLoadArrayLength(masm(), edx, ecx, &miss);
|
3095
3104
|
__ bind(&miss);
|
3096
|
-
__ DecrementCounter(
|
3105
|
+
__ DecrementCounter(counters->keyed_load_array_length(), 1);
|
3097
3106
|
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
3098
3107
|
|
3099
3108
|
// Return the generated code.
|
@@ -3109,7 +3118,8 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
|
|
3109
3118
|
// -----------------------------------
|
3110
3119
|
Label miss;
|
3111
3120
|
|
3112
|
-
|
3121
|
+
Counters* counters = isolate()->counters();
|
3122
|
+
__ IncrementCounter(counters->keyed_load_string_length(), 1);
|
3113
3123
|
|
3114
3124
|
// Check that the name has not changed.
|
3115
3125
|
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
|
@@ -3117,7 +3127,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
|
|
3117
3127
|
|
3118
3128
|
GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true);
|
3119
3129
|
__ bind(&miss);
|
3120
|
-
__ DecrementCounter(
|
3130
|
+
__ DecrementCounter(counters->keyed_load_string_length(), 1);
|
3121
3131
|
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
3122
3132
|
|
3123
3133
|
// Return the generated code.
|
@@ -3133,7 +3143,8 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
|
|
3133
3143
|
// -----------------------------------
|
3134
3144
|
Label miss;
|
3135
3145
|
|
3136
|
-
|
3146
|
+
Counters* counters = isolate()->counters();
|
3147
|
+
__ IncrementCounter(counters->keyed_load_function_prototype(), 1);
|
3137
3148
|
|
3138
3149
|
// Check that the name has not changed.
|
3139
3150
|
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
|
@@ -3141,7 +3152,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
|
|
3141
3152
|
|
3142
3153
|
GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
|
3143
3154
|
__ bind(&miss);
|
3144
|
-
__ DecrementCounter(
|
3155
|
+
__ DecrementCounter(counters->keyed_load_function_prototype(), 1);
|
3145
3156
|
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
3146
3157
|
|
3147
3158
|
// Return the generated code.
|
@@ -3181,7 +3192,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) {
|
|
3181
3192
|
// Load the result and make sure it's not the hole.
|
3182
3193
|
__ mov(ebx, Operand(ecx, eax, times_2,
|
3183
3194
|
FixedArray::kHeaderSize - kHeapObjectTag));
|
3184
|
-
__ cmp(ebx,
|
3195
|
+
__ cmp(ebx, factory()->the_hole_value());
|
3185
3196
|
__ j(equal, &miss, not_taken);
|
3186
3197
|
__ mov(eax, ebx);
|
3187
3198
|
__ ret(0);
|
@@ -3194,37 +3205,6 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) {
|
|
3194
3205
|
}
|
3195
3206
|
|
3196
3207
|
|
3197
|
-
MaybeObject* KeyedLoadStubCompiler::CompileLoadPixelArray(JSObject* receiver) {
|
3198
|
-
// ----------- S t a t e -------------
|
3199
|
-
// -- eax : key
|
3200
|
-
// -- edx : receiver
|
3201
|
-
// -- esp[0] : return address
|
3202
|
-
// -----------------------------------
|
3203
|
-
Label miss;
|
3204
|
-
|
3205
|
-
// Check that the map matches.
|
3206
|
-
__ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false);
|
3207
|
-
|
3208
|
-
GenerateFastPixelArrayLoad(masm(),
|
3209
|
-
edx,
|
3210
|
-
eax,
|
3211
|
-
ecx,
|
3212
|
-
ebx,
|
3213
|
-
eax,
|
3214
|
-
&miss,
|
3215
|
-
&miss,
|
3216
|
-
&miss);
|
3217
|
-
|
3218
|
-
// Handle load cache miss.
|
3219
|
-
__ bind(&miss);
|
3220
|
-
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Miss));
|
3221
|
-
__ jmp(ic, RelocInfo::CODE_TARGET);
|
3222
|
-
|
3223
|
-
// Return the generated code.
|
3224
|
-
return GetCode(NORMAL, NULL);
|
3225
|
-
}
|
3226
|
-
|
3227
|
-
|
3228
3208
|
// Specialized stub for constructing objects from functions which only have only
|
3229
3209
|
// simple assignments of the form this.x = ...; in their body.
|
3230
3210
|
MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
|
@@ -3241,7 +3221,7 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
|
|
3241
3221
|
// code for the function thereby hitting the break points.
|
3242
3222
|
__ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
3243
3223
|
__ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kDebugInfoOffset));
|
3244
|
-
__ cmp(ebx,
|
3224
|
+
__ cmp(ebx, factory()->undefined_value());
|
3245
3225
|
__ j(not_equal, &generic_stub_call, not_taken);
|
3246
3226
|
#endif
|
3247
3227
|
|
@@ -3278,7 +3258,7 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
|
|
3278
3258
|
// ebx: initial map
|
3279
3259
|
// edx: JSObject (untagged)
|
3280
3260
|
__ mov(Operand(edx, JSObject::kMapOffset), ebx);
|
3281
|
-
__ mov(ebx,
|
3261
|
+
__ mov(ebx, factory()->empty_fixed_array());
|
3282
3262
|
__ mov(Operand(edx, JSObject::kPropertiesOffset), ebx);
|
3283
3263
|
__ mov(Operand(edx, JSObject::kElementsOffset), ebx);
|
3284
3264
|
|
@@ -3295,7 +3275,7 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
|
|
3295
3275
|
__ lea(ecx, Operand(esp, eax, times_4, 1 * kPointerSize));
|
3296
3276
|
|
3297
3277
|
// Use edi for holding undefined which is used in several places below.
|
3298
|
-
__ mov(edi,
|
3278
|
+
__ mov(edi, factory()->undefined_value());
|
3299
3279
|
|
3300
3280
|
// eax: argc
|
3301
3281
|
// ecx: first argument
|
@@ -3347,15 +3327,16 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
|
|
3347
3327
|
__ pop(ecx);
|
3348
3328
|
__ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
|
3349
3329
|
__ push(ecx);
|
3350
|
-
|
3351
|
-
__ IncrementCounter(
|
3330
|
+
Counters* counters = isolate()->counters();
|
3331
|
+
__ IncrementCounter(counters->constructed_objects(), 1);
|
3332
|
+
__ IncrementCounter(counters->constructed_objects_stub(), 1);
|
3352
3333
|
__ ret(0);
|
3353
3334
|
|
3354
3335
|
// Jump to the generic stub in case the specialized code cannot handle the
|
3355
3336
|
// construction.
|
3356
3337
|
__ bind(&generic_stub_call);
|
3357
|
-
Code
|
3358
|
-
|
3338
|
+
Handle<Code> generic_construct_stub =
|
3339
|
+
isolate()->builtins()->JSConstructStubGeneric();
|
3359
3340
|
__ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
|
3360
3341
|
|
3361
3342
|
// Return the generated code.
|
@@ -3364,7 +3345,7 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
|
|
3364
3345
|
|
3365
3346
|
|
3366
3347
|
MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
|
3367
|
-
ExternalArrayType array_type, Code::Flags flags) {
|
3348
|
+
JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) {
|
3368
3349
|
// ----------- S t a t e -------------
|
3369
3350
|
// -- eax : key
|
3370
3351
|
// -- edx : receiver
|
@@ -3380,25 +3361,9 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
|
|
3380
3361
|
__ test(eax, Immediate(kSmiTagMask));
|
3381
3362
|
__ j(not_zero, &slow, not_taken);
|
3382
3363
|
|
3383
|
-
//
|
3384
|
-
__
|
3385
|
-
// Check that the receiver does not require access checks. We need
|
3386
|
-
// to check this explicitly since this generic stub does not perform
|
3387
|
-
// map checks.
|
3388
|
-
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
|
3389
|
-
1 << Map::kIsAccessCheckNeeded);
|
3390
|
-
__ j(not_zero, &slow, not_taken);
|
3391
|
-
|
3392
|
-
__ CmpInstanceType(ecx, JS_OBJECT_TYPE);
|
3393
|
-
__ j(not_equal, &slow, not_taken);
|
3394
|
-
|
3395
|
-
// Check that the elements array is the appropriate type of
|
3396
|
-
// ExternalArray.
|
3364
|
+
// Check that the map matches.
|
3365
|
+
__ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false);
|
3397
3366
|
__ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
|
3398
|
-
Handle<Map> map(Heap::MapForExternalArrayType(array_type));
|
3399
|
-
__ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
|
3400
|
-
Immediate(map));
|
3401
|
-
__ j(not_equal, &slow, not_taken);
|
3402
3367
|
|
3403
3368
|
// eax: key, known to be a smi.
|
3404
3369
|
// edx: receiver, known to be a JSObject.
|
@@ -3409,21 +3374,21 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
|
|
3409
3374
|
__ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
|
3410
3375
|
// Unsigned comparison catches both negative and too-large values.
|
3411
3376
|
__ j(above_equal, &slow);
|
3412
|
-
|
3413
3377
|
__ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
|
3414
3378
|
// ebx: base pointer of external storage
|
3415
3379
|
switch (array_type) {
|
3416
3380
|
case kExternalByteArray:
|
3417
|
-
__ movsx_b(
|
3381
|
+
__ movsx_b(eax, Operand(ebx, ecx, times_1, 0));
|
3418
3382
|
break;
|
3419
3383
|
case kExternalUnsignedByteArray:
|
3420
|
-
|
3384
|
+
case kExternalPixelArray:
|
3385
|
+
__ movzx_b(eax, Operand(ebx, ecx, times_1, 0));
|
3421
3386
|
break;
|
3422
3387
|
case kExternalShortArray:
|
3423
|
-
__ movsx_w(
|
3388
|
+
__ movsx_w(eax, Operand(ebx, ecx, times_2, 0));
|
3424
3389
|
break;
|
3425
3390
|
case kExternalUnsignedShortArray:
|
3426
|
-
__ movzx_w(
|
3391
|
+
__ movzx_w(eax, Operand(ebx, ecx, times_2, 0));
|
3427
3392
|
break;
|
3428
3393
|
case kExternalIntArray:
|
3429
3394
|
case kExternalUnsignedIntArray:
|
@@ -3498,7 +3463,6 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
|
|
3498
3463
|
__ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
|
3499
3464
|
__ ret(0);
|
3500
3465
|
} else {
|
3501
|
-
__ mov(eax, ecx);
|
3502
3466
|
__ SmiTag(eax);
|
3503
3467
|
__ ret(0);
|
3504
3468
|
}
|
@@ -3512,7 +3476,8 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
|
|
3512
3476
|
|
3513
3477
|
// Slow case: Jump to runtime.
|
3514
3478
|
__ bind(&slow);
|
3515
|
-
|
3479
|
+
Counters* counters = isolate()->counters();
|
3480
|
+
__ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
|
3516
3481
|
// ----------- S t a t e -------------
|
3517
3482
|
// -- eax : key
|
3518
3483
|
// -- edx : receiver
|
@@ -3533,7 +3498,7 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
|
|
3533
3498
|
|
3534
3499
|
|
3535
3500
|
MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
|
3536
|
-
ExternalArrayType array_type, Code::Flags flags) {
|
3501
|
+
JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) {
|
3537
3502
|
// ----------- S t a t e -------------
|
3538
3503
|
// -- eax : value
|
3539
3504
|
// -- ecx : key
|
@@ -3545,30 +3510,16 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
|
|
3545
3510
|
// Check that the object isn't a smi.
|
3546
3511
|
__ test(edx, Immediate(kSmiTagMask));
|
3547
3512
|
__ j(zero, &slow);
|
3548
|
-
|
3549
|
-
|
3550
|
-
|
3551
|
-
|
3552
|
-
__ test_b(FieldOperand(edi, Map::kBitFieldOffset),
|
3553
|
-
1 << Map::kIsAccessCheckNeeded);
|
3554
|
-
__ j(not_zero, &slow);
|
3513
|
+
|
3514
|
+
// Check that the map matches.
|
3515
|
+
__ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false);
|
3516
|
+
|
3555
3517
|
// Check that the key is a smi.
|
3556
3518
|
__ test(ecx, Immediate(kSmiTagMask));
|
3557
3519
|
__ j(not_zero, &slow);
|
3558
|
-
// Get the instance type from the map of the receiver.
|
3559
|
-
__ CmpInstanceType(edi, JS_OBJECT_TYPE);
|
3560
|
-
__ j(not_equal, &slow);
|
3561
|
-
|
3562
|
-
// Check that the elements array is the appropriate type of
|
3563
|
-
// ExternalArray.
|
3564
|
-
// eax: value
|
3565
|
-
// edx: receiver, a JSObject
|
3566
|
-
// ecx: key, a smi
|
3567
|
-
__ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
|
3568
|
-
__ CheckMap(edi, Handle<Map>(Heap::MapForExternalArrayType(array_type)),
|
3569
|
-
&slow, true);
|
3570
3520
|
|
3571
3521
|
// Check that the index is in range.
|
3522
|
+
__ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
|
3572
3523
|
__ mov(ebx, ecx);
|
3573
3524
|
__ SmiUntag(ebx);
|
3574
3525
|
__ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset));
|
@@ -3583,13 +3534,28 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
|
|
3583
3534
|
// edi: elements array
|
3584
3535
|
// ebx: untagged index
|
3585
3536
|
__ test(eax, Immediate(kSmiTagMask));
|
3586
|
-
|
3537
|
+
if (array_type == kExternalPixelArray)
|
3538
|
+
__ j(not_equal, &slow);
|
3539
|
+
else
|
3540
|
+
__ j(not_equal, &check_heap_number);
|
3541
|
+
|
3587
3542
|
// smi case
|
3588
3543
|
__ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed.
|
3589
3544
|
__ SmiUntag(ecx);
|
3590
3545
|
__ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
|
3591
3546
|
// ecx: base pointer of external storage
|
3592
3547
|
switch (array_type) {
|
3548
|
+
case kExternalPixelArray:
|
3549
|
+
{ // Clamp the value to [0..255].
|
3550
|
+
NearLabel done;
|
3551
|
+
__ test(ecx, Immediate(0xFFFFFF00));
|
3552
|
+
__ j(zero, &done);
|
3553
|
+
__ setcc(negative, ecx); // 1 if negative, 0 if positive.
|
3554
|
+
__ dec_b(ecx); // 0 if negative, 255 if positive.
|
3555
|
+
__ bind(&done);
|
3556
|
+
}
|
3557
|
+
__ mov_b(Operand(edi, ebx, times_1, 0), ecx);
|
3558
|
+
break;
|
3593
3559
|
case kExternalByteArray:
|
3594
3560
|
case kExternalUnsignedByteArray:
|
3595
3561
|
__ mov_b(Operand(edi, ebx, times_1, 0), ecx);
|
@@ -3615,87 +3581,101 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
|
|
3615
3581
|
}
|
3616
3582
|
__ ret(0); // Return the original value.
|
3617
3583
|
|
3618
|
-
|
3619
|
-
|
3620
|
-
|
3621
|
-
|
3622
|
-
|
3623
|
-
|
3624
|
-
|
3625
|
-
|
3626
|
-
|
3627
|
-
|
3628
|
-
|
3629
|
-
|
3630
|
-
|
3631
|
-
|
3632
|
-
|
3633
|
-
|
3634
|
-
|
3635
|
-
|
3636
|
-
|
3637
|
-
|
3638
|
-
|
3639
|
-
|
3640
|
-
|
3641
|
-
|
3642
|
-
|
3643
|
-
|
3644
|
-
|
3645
|
-
|
3646
|
-
|
3647
|
-
|
3648
|
-
|
3649
|
-
|
3650
|
-
|
3651
|
-
__ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
|
3652
|
-
// ecx: untagged integer value
|
3653
|
-
switch (array_type) {
|
3654
|
-
case kExternalByteArray:
|
3655
|
-
case kExternalUnsignedByteArray:
|
3656
|
-
__ mov_b(Operand(edi, ebx, times_1, 0), ecx);
|
3657
|
-
break;
|
3658
|
-
case kExternalShortArray:
|
3659
|
-
case kExternalUnsignedShortArray:
|
3660
|
-
__ mov_w(Operand(edi, ebx, times_2, 0), ecx);
|
3661
|
-
break;
|
3662
|
-
default:
|
3663
|
-
UNREACHABLE();
|
3664
|
-
break;
|
3665
|
-
}
|
3666
|
-
} else {
|
3667
|
-
if (CpuFeatures::IsSupported(SSE3)) {
|
3668
|
-
CpuFeatures::Scope scope(SSE3);
|
3669
|
-
// fisttp stores values as signed integers. To represent the
|
3670
|
-
// entire range of int and unsigned int arrays, store as a
|
3671
|
-
// 64-bit int and discard the high 32 bits.
|
3672
|
-
// If the value is NaN or +/-infinity, the result is 0x80000000,
|
3673
|
-
// which is automatically zero when taken mod 2^n, n < 32.
|
3674
|
-
__ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
|
3675
|
-
__ sub(Operand(esp), Immediate(2 * kPointerSize));
|
3676
|
-
__ fisttp_d(Operand(esp, 0));
|
3677
|
-
__ pop(ecx);
|
3678
|
-
__ add(Operand(esp), Immediate(kPointerSize));
|
3679
|
-
} else {
|
3584
|
+
// TODO(danno): handle heap number -> pixel array conversion
|
3585
|
+
if (array_type != kExternalPixelArray) {
|
3586
|
+
__ bind(&check_heap_number);
|
3587
|
+
// eax: value
|
3588
|
+
// edx: receiver
|
3589
|
+
// ecx: key
|
3590
|
+
// edi: elements array
|
3591
|
+
// ebx: untagged index
|
3592
|
+
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
|
3593
|
+
Immediate(factory()->heap_number_map()));
|
3594
|
+
__ j(not_equal, &slow);
|
3595
|
+
|
3596
|
+
// The WebGL specification leaves the behavior of storing NaN and
|
3597
|
+
// +/-Infinity into integer arrays basically undefined. For more
|
3598
|
+
// reproducible behavior, convert these to zero.
|
3599
|
+
__ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
|
3600
|
+
// ebx: untagged index
|
3601
|
+
// edi: base pointer of external storage
|
3602
|
+
if (array_type == kExternalFloatArray) {
|
3603
|
+
__ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
|
3604
|
+
__ fstp_s(Operand(edi, ebx, times_4, 0));
|
3605
|
+
__ ret(0);
|
3606
|
+
} else {
|
3607
|
+
// Perform float-to-int conversion with truncation (round-to-zero)
|
3608
|
+
// behavior.
|
3609
|
+
|
3610
|
+
// For the moment we make the slow call to the runtime on
|
3611
|
+
// processors that don't support SSE2. The code in IntegerConvert
|
3612
|
+
// (code-stubs-ia32.cc) is roughly what is needed here though the
|
3613
|
+
// conversion failure case does not need to be handled.
|
3614
|
+
if (CpuFeatures::IsSupported(SSE2)) {
|
3615
|
+
if (array_type != kExternalIntArray &&
|
3616
|
+
array_type != kExternalUnsignedIntArray) {
|
3680
3617
|
ASSERT(CpuFeatures::IsSupported(SSE2));
|
3681
3618
|
CpuFeatures::Scope scope(SSE2);
|
3682
|
-
|
3683
|
-
//
|
3684
|
-
|
3685
|
-
|
3686
|
-
|
3687
|
-
|
3688
|
-
|
3689
|
-
|
3690
|
-
|
3691
|
-
|
3692
|
-
|
3693
|
-
|
3619
|
+
__ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
|
3620
|
+
// ecx: untagged integer value
|
3621
|
+
switch (array_type) {
|
3622
|
+
case kExternalPixelArray:
|
3623
|
+
{ // Clamp the value to [0..255].
|
3624
|
+
NearLabel done;
|
3625
|
+
__ test(ecx, Immediate(0xFFFFFF00));
|
3626
|
+
__ j(zero, &done);
|
3627
|
+
__ setcc(negative, ecx); // 1 if negative, 0 if positive.
|
3628
|
+
__ dec_b(ecx); // 0 if negative, 255 if positive.
|
3629
|
+
__ bind(&done);
|
3630
|
+
}
|
3631
|
+
__ mov_b(Operand(edi, ebx, times_1, 0), ecx);
|
3632
|
+
break;
|
3633
|
+
case kExternalByteArray:
|
3634
|
+
case kExternalUnsignedByteArray:
|
3635
|
+
__ mov_b(Operand(edi, ebx, times_1, 0), ecx);
|
3636
|
+
break;
|
3637
|
+
case kExternalShortArray:
|
3638
|
+
case kExternalUnsignedShortArray:
|
3639
|
+
__ mov_w(Operand(edi, ebx, times_2, 0), ecx);
|
3640
|
+
break;
|
3641
|
+
default:
|
3642
|
+
UNREACHABLE();
|
3643
|
+
break;
|
3644
|
+
}
|
3645
|
+
} else {
|
3646
|
+
if (CpuFeatures::IsSupported(SSE3)) {
|
3647
|
+
CpuFeatures::Scope scope(SSE3);
|
3648
|
+
// fisttp stores values as signed integers. To represent the
|
3649
|
+
// entire range of int and unsigned int arrays, store as a
|
3650
|
+
// 64-bit int and discard the high 32 bits.
|
3651
|
+
// If the value is NaN or +/-infinity, the result is 0x80000000,
|
3652
|
+
// which is automatically zero when taken mod 2^n, n < 32.
|
3653
|
+
__ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
|
3654
|
+
__ sub(Operand(esp), Immediate(2 * kPointerSize));
|
3655
|
+
__ fisttp_d(Operand(esp, 0));
|
3656
|
+
__ pop(ecx);
|
3657
|
+
__ add(Operand(esp), Immediate(kPointerSize));
|
3658
|
+
} else {
|
3659
|
+
ASSERT(CpuFeatures::IsSupported(SSE2));
|
3660
|
+
CpuFeatures::Scope scope(SSE2);
|
3661
|
+
// We can easily implement the correct rounding behavior for the
|
3662
|
+
// range [0, 2^31-1]. For the time being, to keep this code simple,
|
3663
|
+
// make the slow runtime call for values outside this range.
|
3664
|
+
// Note: we could do better for signed int arrays.
|
3665
|
+
__ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
|
3666
|
+
// We will need the key if we have to make the slow runtime call.
|
3667
|
+
__ push(ecx);
|
3668
|
+
__ LoadPowerOf2(xmm1, ecx, 31);
|
3669
|
+
__ pop(ecx);
|
3670
|
+
__ ucomisd(xmm1, xmm0);
|
3671
|
+
__ j(above_equal, &slow);
|
3672
|
+
__ cvttsd2si(ecx, Operand(xmm0));
|
3673
|
+
}
|
3674
|
+
// ecx: untagged integer value
|
3675
|
+
__ mov(Operand(edi, ebx, times_4, 0), ecx);
|
3694
3676
|
}
|
3695
|
-
//
|
3696
|
-
__ mov(Operand(edi, ebx, times_4, 0), ecx);
|
3677
|
+
__ ret(0); // Return original value.
|
3697
3678
|
}
|
3698
|
-
__ ret(0); // Return original value.
|
3699
3679
|
}
|
3700
3680
|
}
|
3701
3681
|
|
@@ -3712,10 +3692,13 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
|
|
3712
3692
|
__ push(edx);
|
3713
3693
|
__ push(ecx);
|
3714
3694
|
__ push(eax);
|
3715
|
-
__ push(
|
3695
|
+
__ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes
|
3696
|
+
__ push(Immediate(Smi::FromInt(
|
3697
|
+
Code::ExtractExtraICStateFromFlags(flags) & kStrictMode)));
|
3698
|
+
__ push(ebx); // return address
|
3716
3699
|
|
3717
3700
|
// Do tail-call to runtime routine.
|
3718
|
-
__ TailCallRuntime(Runtime::kSetProperty,
|
3701
|
+
__ TailCallRuntime(Runtime::kSetProperty, 5, 1);
|
3719
3702
|
|
3720
3703
|
return GetCode(flags);
|
3721
3704
|
}
|