Revision: 11978
Author:   [email protected]
Date:     Tue Jul  3 03:03:19 2012
Log:      Version 3.12.7

Fixed lazy compilation for strict eval scopes. (Chromium issue 135066)

Made MACOSX_DEPLOYMENT_TARGET configurable in GYP. (issue 2151)

Report "hidden properties" in heap profiler for properties case. (issue 2212)

Activated optimization of packed arrays by default.

Performance and stability improvements on all platforms.
http://code.google.com/p/v8/source/detail?r=11978

Added:
 /trunk/test/mjsunit/regress/regress-crbug-135066.js
 /trunk/test/mjsunit/typed-array-slice.js
 /trunk/tools/android-run.py
 /trunk/tools/android-sync.sh
Modified:
 /trunk/ChangeLog
 /trunk/Makefile
 /trunk/build/standalone.gypi
 /trunk/src/ast.cc
 /trunk/src/flag-definitions.h
 /trunk/src/hydrogen.cc
 /trunk/src/hydrogen.h
 /trunk/src/liveedit.cc
 /trunk/src/profile-generator.cc
 /trunk/src/scopes.cc
 /trunk/src/scopes.h
 /trunk/src/v8threads.cc
 /trunk/src/v8threads.h
 /trunk/src/version.cc
 /trunk/test/cctest/cctest.status
 /trunk/test/cctest/test-heap-profiler.cc
 /trunk/test/cctest/testcfg.py
 /trunk/test/mjsunit/external-array.js
 /trunk/test/mjsunit/mjsunit.status
 /trunk/tools/test-wrapper-gypbuild.py
 /trunk/tools/test.py

=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-crbug-135066.js Tue Jul 3 03:03:19 2012
@@ -0,0 +1,53 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Filler long enough to trigger lazy parsing.
+var filler = "//" + new Array(1024).join('x');
+
+// Test strict eval in global context.
+eval(
+  "'use strict';" +
+  "var x = 23;" +
+  "var f = function bozo1() {" +
+  "  return x;" +
+  "};" +
+  "assertSame(23, f());" +
+  filler
+);
+
+// Test default eval in strict context.
+(function() {
+  "use strict";
+  eval(
+    "var y = 42;" +
+    "var g = function bozo2() {" +
+    "  return y;" +
+    "};" +
+    "assertSame(42, g());" +
+    filler
+  );
+})();
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/typed-array-slice.js    Tue Jul  3 03:03:19 2012
@@ -0,0 +1,61 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// This is a regression test for overlapping key and value registers.
+
+var types = [Array, Int8Array, Uint8Array, Int16Array, Uint16Array,
+             Int32Array, Uint32Array, Uint8ClampedArray, Float32Array,
+             Float64Array];
+
+var results1 = [-2, -2, 254, -2, 65534, -2, 4294967294, 0, -2, -2];
+var results2 = [undefined, -1, 255, -1, 65535, -1, 4294967295, 0, -1, -1];
+var results3 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+var results4 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
+
+const kElementCount = 40;
+
+function do_slice(a) {
+  return Array.prototype.slice.call(a, 4, 8);
+}
+
+for (var t = 0; t < types.length; t++) {
+  var type = types[t];
+  var a = new type(kElementCount);
+  for (var i = 0; i < kElementCount; ++i ) {
+    a[i] = i-6;
+  }
+  delete a[5];
+  var sliced = do_slice(a);
+
+  %ClearFunctionTypeFeedback(do_slice);
+  assertEquals(results1[t], sliced[0]);
+  assertEquals(results2[t], sliced[1]);
+  assertEquals(results3[t], sliced[2]);
+  assertEquals(results4[t], sliced[3]);
+}
=======================================
--- /dev/null
+++ /trunk/tools/android-run.py Tue Jul  3 03:03:19 2012
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#     * Neither the name of Google Inc. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This script executes the passed command line on Android device
+# using 'adb shell' command. Unfortunately, 'adb shell' always
+# returns exit code 0, ignoring the exit code of executed command.
+# Since we need to return non-zero exit code if the command failed,
+# we augment the passed command line with exit code checking statement
+# and output special error string in case of non-zero exit code.
+# Then we parse the output of 'adb shell' and look for that error string.
+
+import os
+from os.path import join, dirname, abspath
+import subprocess
+import sys
+import tempfile
+
+def Check(output, errors):
+  failed = any([s.startswith('/system/bin/sh:') or s.startswith('Error')
+                for s in output.split('\n')])
+  return 1 if failed else 0
+
+def Execute(cmdline):
+  (fd_out, outname) = tempfile.mkstemp()
+  (fd_err, errname) = tempfile.mkstemp()
+  process = subprocess.Popen(
+    args=cmdline,
+    shell=True,
+    stdout=fd_out,
+    stderr=fd_err,
+  )
+  exit_code = process.wait()
+  os.close(fd_out)
+  os.close(fd_err)
+  output = file(outname).read()
+  errors = file(errname).read()
+  os.unlink(outname)
+  os.unlink(errname)
+  sys.stdout.write(output)
+  sys.stderr.write(errors)
+  return exit_code or Check(output, errors)
+
+def Escape(arg):
+  def ShouldEscape():
+    for x in arg:
+      if not x.isalnum() and x != '-' and x != '_':
+        return True
+    return False
+
+  return arg if not ShouldEscape() else '"%s"' % (arg.replace('"', '\\"'))
+
+def WriteToTemporaryFile(data):
+  (fd, fname) = tempfile.mkstemp()
+  os.close(fd)
+  tmp_file = open(fname, "w")
+  tmp_file.write(data)
+  tmp_file.close()
+  return fname
+
+def Main():
+  if (len(sys.argv) == 1):
+    print("Usage: %s <command-to-run-on-device>" % sys.argv[0])
+    return 1
+  workspace = abspath(join(dirname(sys.argv[0]), '..'))
+  android_workspace = os.getenv("ANDROID_V8", "/data/local/v8")
+  args = [Escape(arg) for arg in sys.argv[1:]]
+  script = (" ".join(args) + "\n"
+            "if [ $? -ne 0 ]\n"
+            "  then echo \"Error returned by test\";\n"
+            "fi\n")
+  script = script.replace(workspace, android_workspace)
+  script_file = WriteToTemporaryFile(script)
+  android_script_file = android_workspace + "/" + script_file
+  command =  ("adb push '%s' %s;" % (script_file, android_script_file) +
+              "adb shell 'sh %s';" % android_script_file +
+              "adb shell 'rm %s'" % android_script_file)
+  error_code = Execute(command)
+  os.unlink(script_file)
+  return error_code
+
+if __name__ == '__main__':
+  sys.exit(Main())
=======================================
--- /dev/null
+++ /trunk/tools/android-sync.sh        Tue Jul  3 03:03:19 2012
@@ -0,0 +1,79 @@
+#!/bin/bash
+# Copyright 2012 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#     * Neither the name of Google Inc. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This script pushes android binaries and test data to the device.
+# The first argument can be either "android.release" or "android.debug".
+# The second argument is a relative path to the output directory with binaries.
+# The third argument is the absolute path to the V8 directory on the host.
+# The fourth argument is the absolute path to the V8 directory on the device.
+
+if [ ${#@} -lt 4 ] ; then
+  echo "Error: need 4 arguments"
+  exit 1
+fi
+
+ARCH_MODE=$1
+OUTDIR=$2
+HOST_V8=$3
+ANDROID_V8=$4
+
+function sync_file {
+  local FILE=$1
+  local ANDROID_HASH=$(adb shell "md5 \"$ANDROID_V8/$FILE\"")
+  local HOST_HASH=$(md5sum "$HOST_V8/$FILE")
+  if [ "${ANDROID_HASH%% *}" != "${HOST_HASH%% *}" ]; then
+    adb push "$HOST_V8/$FILE" "$ANDROID_V8/$FILE" &> /dev/null
+  fi
+  echo -n "."
+}
+
+function sync_dir {
+  local DIR=$1
+  echo -n "sync to $ANDROID_V8/$DIR"
+  for FILE in $(find "$HOST_V8/$DIR" -type f); do
+    local RELATIVE_FILE=${FILE:${#HOST_V8}}
+    sync_file "$RELATIVE_FILE"
+  done
+  echo ""
+}
+
+echo -n "sync to $ANDROID_V8/$OUTDIR/$ARCH_MODE"
+sync_file "$OUTDIR/$ARCH_MODE/cctest"
+sync_file "$OUTDIR/$ARCH_MODE/d8"
+sync_file "$OUTDIR/$ARCH_MODE/preparser"
+echo ""
+echo -n "sync to $ANDROID_V8/tools"
+sync_file tools/consarray.js
+sync_file tools/codemap.js
+sync_file tools/csvparser.js
+sync_file tools/profile.js
+sync_file tools/splaytree.js
+echo ""
+sync_dir test/message
+sync_dir test/mjsunit
+sync_dir test/preparser
=======================================
--- /trunk/ChangeLog    Fri Jun 29 08:15:45 2012
+++ /trunk/ChangeLog    Tue Jul  3 03:03:19 2012
@@ -1,3 +1,19 @@
+2012-07-03: Version 3.12.7
+
+        Fixed lazy compilation for strict eval scopes.
+        (Chromium issue 135066)
+
+        Made MACOSX_DEPLOYMENT_TARGET configurable in GYP.
+        (issue 2151)
+
+        Report "hidden properties" in heap profiler for properties case.
+        (issue 2212)
+
+        Activated optimization of packed arrays by default.
+
+        Performance and stability improvements on all platforms.
+
+
 2012-06-29: Version 3.12.6

         Cleaned up hardfp ABI detection for ARM (V8 issue 2140).
=======================================
--- /trunk/Makefile     Wed Jun 20 04:29:00 2012
+++ /trunk/Makefile     Tue Jul  3 03:03:19 2012
@@ -35,6 +35,7 @@
 TESTFLAGS ?=
 ANDROID_NDK_ROOT ?=
ANDROID_TOOL_PREFIX = $(ANDROID_NDK_ROOT)/toolchain/bin/arm-linux-androideabi
+ANDROID_V8 ?= /data/local/v8

 # Special build flags. Use them like this: "make library=shared"

@@ -107,7 +108,7 @@
 # - every combination <arch>.<mode>, e.g. "ia32.release"
 # - "native": current host's architecture, release mode
 # - any of the above with .check appended, e.g. "ia32.release.check"
-# - "android": cross-compile for Android/ARM (release mode)
+# - "android": cross-compile for Android/ARM
 # - default (no target specified): build all DEFAULT_ARCHES and MODES
 # - "check": build all targets and run all tests
 # - "<arch>.clean" for any <arch> in ARCHES
@@ -120,6 +121,7 @@
 ARCHES = ia32 x64 arm mips
 DEFAULT_ARCHES = ia32 x64 arm
 MODES = release debug
+ANDROID_MODES = android.release android.debug

 # List of files that trigger Makefile regeneration:
 GYPFILES = build/all.gyp build/common.gypi build/standalone.gypi \
@@ -166,8 +168,9 @@
                 CXX="$(CXX)" LINK="$(LINK)" BUILDTYPE=Release \
                 builddir="$(shell pwd)/$(OUTDIR)/$@"

-# TODO(jkummerow): add "android.debug" when we need it.
-android android.release: $(OUTDIR)/Makefile.android
+android: $(ANDROID_MODES)
+
+$(ANDROID_MODES): $(OUTDIR)/Makefile.android
        @$(MAKE) -C "$(OUTDIR)" -f Makefile.android \
                CXX="$(ANDROID_TOOL_PREFIX)-g++" \
                AR="$(ANDROID_TOOL_PREFIX)-ar" \
@@ -175,8 +178,9 @@
                CC="$(ANDROID_TOOL_PREFIX)-gcc" \
                LD="$(ANDROID_TOOL_PREFIX)-ld" \
                LINK="$(ANDROID_TOOL_PREFIX)-g++" \
-               BUILDTYPE=Release \
-               builddir="$(shell pwd)/$(OUTDIR)/android.release"
+               BUILDTYPE=$(shell echo $(subst .,,$(suffix $@)) | \
+                           python -c "print raw_input().capitalize()") \
+               builddir="$(shell pwd)/$(OUTDIR)/$@"

 # Test targets.
 check: all
@@ -196,6 +200,17 @@
        @tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR) \
            --arch-and-mode=$(basename $@) $(TESTFLAGS)

+$(addsuffix .sync, $(ANDROID_MODES)): $$(basename $$@)
+       @tools/android-sync.sh $(basename $@) $(OUTDIR) \
+                              $(shell pwd) $(ANDROID_V8)
+
+$(addsuffix .check, $(ANDROID_MODES)): $$(basename $$@).sync
+       @tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR) \
+            --arch-and-mode=$(basename $@) \
+            --special-command="tools/android-run.py @"
+
+android.check: android.release.check android.debug.check
+
 native.check: native
        @tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR)/native \
            --arch-and-mode=. $(TESTFLAGS)
=======================================
--- /trunk/build/standalone.gypi        Fri May 11 08:02:09 2012
+++ /trunk/build/standalone.gypi        Tue Jul  3 03:03:19 2012
@@ -33,6 +33,7 @@
     'component%': 'static_library',
     'visibility%': 'hidden',
     'msvs_multi_core_compile%': '1',
+    'mac_deployment_target%': '10.5',
     'variables': {
       'variables': {
         'variables': {
@@ -191,7 +192,8 @@
           'GCC_TREAT_WARNINGS_AS_ERRORS': 'YES',    # -Werror
           'GCC_VERSION': '4.2',
           'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES',  # -Wnewline-eof
- 'MACOSX_DEPLOYMENT_TARGET': '10.4', # -mmacosx-version-min=10.4
+          # MACOSX_DEPLOYMENT_TARGET maps to -mmacosx-version-min
+          'MACOSX_DEPLOYMENT_TARGET': '<(mac_deployment_target)',
           'PREBINDING': 'NO',                       # No -Wl,-prebind
           'SYMROOT': '<(DEPTH)/xcodebuild',
           'USE_HEADERMAP': 'NO',
=======================================
--- /trunk/src/ast.cc   Thu Jun 28 08:04:22 2012
+++ /trunk/src/ast.cc   Tue Jul  3 03:03:19 2012
@@ -1048,7 +1048,6 @@
 REGULAR_NODE(Literal)
 REGULAR_NODE(ObjectLiteral)
 REGULAR_NODE(RegExpLiteral)
-REGULAR_NODE(ArrayLiteral)
 REGULAR_NODE(Assignment)
 REGULAR_NODE(Throw)
 REGULAR_NODE(Property)
@@ -1078,6 +1077,7 @@
 DONT_OPTIMIZE_NODE(DebuggerStatement)
 DONT_OPTIMIZE_NODE(SharedFunctionInfoLiteral)

+DONT_INLINE_NODE(ArrayLiteral)  // TODO(1322): Allow materialized literals.
 DONT_INLINE_NODE(FunctionLiteral)

 DONT_SELFOPTIMIZE_NODE(DoWhileStatement)
=======================================
--- /trunk/src/flag-definitions.h       Mon Jun 25 02:47:40 2012
+++ /trunk/src/flag-definitions.h       Tue Jul  3 03:03:19 2012
@@ -152,7 +152,7 @@
 DEFINE_implication(harmony_modules, harmony_scoping)

 // Flags for experimental implementation features.
-DEFINE_bool(packed_arrays, false, "optimizes arrays that have no holes")
+DEFINE_bool(packed_arrays, true, "optimizes arrays that have no holes")
 DEFINE_bool(smi_only_arrays, true, "tracks arrays with only smi values")
 DEFINE_bool(clever_optimizations,
             true,
=======================================
--- /trunk/src/hydrogen.cc      Thu Jun 28 08:04:22 2012
+++ /trunk/src/hydrogen.cc      Tue Jul  3 03:03:19 2012
@@ -5748,16 +5748,31 @@
HValue* dependency,
                                                            Handle<Map> map,
                                                            bool is_store) {
-  HInstruction* mapcheck =
- AddInstruction(new(zone()) HCheckMaps(object, map, zone(), dependency));
+  HCheckMaps* mapcheck = new(zone()) HCheckMaps(object, map,
+                                                zone(), dependency);
+  AddInstruction(mapcheck);
+  if (dependency) {
+    mapcheck->ClearGVNFlag(kDependsOnElementsKind);
+  }
+  return BuildUncheckedMonomorphicElementAccess(object, key, val,
+                                                mapcheck, map, is_store);
+}
+
+
+HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
+    HValue* object,
+    HValue* key,
+    HValue* val,
+    HCheckMaps* mapcheck,
+    Handle<Map> map,
+    bool is_store) {
// No GVNFlag is necessary for ElementsKind if there is an explicit dependency // on a HElementsTransition instruction. The flag can also be removed if the
   // map to check has FAST_HOLEY_ELEMENTS, since there can be no further
// ElementsKind transitions. Finally, the dependency can be removed for stores // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
   // generated store code.
-  if (dependency ||
-      (map->elements_kind() == FAST_HOLEY_ELEMENTS) ||
+  if ((map->elements_kind() == FAST_HOLEY_ELEMENTS) ||
       (map->elements_kind() == FAST_ELEMENTS && is_store)) {
     mapcheck->ClearGVNFlag(kDependsOnElementsKind);
   }
@@ -5794,6 +5809,59 @@
   return BuildFastElementAccess(elements, checked_key, val,
                                 map->elements_kind(), is_store);
 }
+
+
+HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad(
+    HValue* object,
+    HValue* key,
+    HValue* val,
+    SmallMapList* maps) {
+ // For polymorphic loads of similar elements kinds (i.e. all tagged or all + // double), always use the "worst case" code without a transition. This is + // much faster than transitioning the elements to the worst case, trading a + // HTransitionElements for a HCheckMaps, and avoiding mutation of the array.
+  bool has_double_maps = false;
+  bool has_smi_or_object_maps = false;
+  bool has_js_array_access = false;
+  bool has_non_js_array_access = false;
+  Handle<Map> most_general_consolidated_map;
+  for (int i = 0; i < maps->length(); ++i) {
+    Handle<Map> map = maps->at(i);
+    // Don't allow mixing of JSArrays with JSObjects.
+    if (map->instance_type() == JS_ARRAY_TYPE) {
+      if (has_non_js_array_access) return NULL;
+      has_js_array_access = true;
+    } else if (has_js_array_access) {
+      return NULL;
+    } else {
+      has_non_js_array_access = true;
+    }
+    // Don't allow mixed, incompatible elements kinds.
+    if (map->has_fast_double_elements()) {
+      if (has_smi_or_object_maps) return NULL;
+      has_double_maps = true;
+    } else if (map->has_fast_smi_or_object_elements()) {
+      if (has_double_maps) return NULL;
+      has_smi_or_object_maps = true;
+    } else {
+      return NULL;
+    }
+    // Remember the most general elements kind, the code for its load will
+    // properly handle all of the more specific cases.
+    if ((i == 0) || IsMoreGeneralElementsKindTransition(
+            most_general_consolidated_map->elements_kind(),
+            map->elements_kind())) {
+      most_general_consolidated_map = map;
+    }
+  }
+  if (!has_double_maps && !has_smi_or_object_maps) return NULL;
+
+  HCheckMaps* check_maps = new(zone()) HCheckMaps(object, maps, zone());
+  AddInstruction(check_maps);
+  HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
+      object, key, val, check_maps, most_general_consolidated_map, false);
+  return instr;
+}


 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
@@ -5809,6 +5877,17 @@
   SmallMapList* maps = prop->GetReceiverTypes();
   bool todo_external_array = false;

+  if (!is_store) {
+    HInstruction* consolidated_load =
+        TryBuildConsolidatedElementLoad(object, key, val, maps);
+    if (consolidated_load != NULL) {
+      AddInstruction(consolidated_load);
+      *has_side_effects |= consolidated_load->HasObservableSideEffects();
+      consolidated_load->set_position(position);
+      return consolidated_load;
+    }
+  }
+
   static const int kNumElementTypes = kElementsKindCount;
   bool type_todo[kNumElementTypes];
   for (int i = 0; i < kNumElementTypes; ++i) {
=======================================
--- /trunk/src/hydrogen.h       Wed Jun 20 04:29:00 2012
+++ /trunk/src/hydrogen.h       Tue Jul  3 03:03:19 2012
@@ -1101,12 +1101,25 @@
                                        ElementsKind elements_kind,
                                        bool is_store);

+  HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
+                                                HValue* key,
+                                                HValue* val,
+                                                SmallMapList* maps);
+
+  HInstruction* BuildUncheckedMonomorphicElementAccess(HValue* object,
+                                                       HValue* key,
+                                                       HValue* val,
+ HCheckMaps* mapcheck,
+                                                       Handle<Map> map,
+                                                       bool is_store);
+
   HInstruction* BuildMonomorphicElementAccess(HValue* object,
                                               HValue* key,
                                               HValue* val,
                                               HValue* dependency,
                                               Handle<Map> map,
                                               bool is_store);
+
   HValue* HandlePolymorphicElementAccess(HValue* object,
                                          HValue* key,
                                          HValue* val,
=======================================
--- /trunk/src/liveedit.cc      Mon Jun 25 02:47:40 2012
+++ /trunk/src/liveedit.cc      Tue Jul  3 03:03:19 2012
@@ -965,12 +965,21 @@


 // Finds all references to original and replaces them with substitution.
-static void ReplaceCodeObject(Code* original, Code* substitution) {
-  ASSERT(!HEAP->InNewSpace(substitution));
+static void ReplaceCodeObject(Handle<Code> original,
+                              Handle<Code> substitution) {
+ // Perform a full GC in order to ensure that we are not in the middle of an
+  // incremental marking phase when we are replacing the code object.
+  // Since we are not in an incremental marking phase we can write pointers
+  // to code objects (that are never in new space) without worrying about
+  // write barriers.
+  HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask,
+                          "liveedit.cc ReplaceCodeObject");
+
+  ASSERT(!HEAP->InNewSpace(*substitution));

   AssertNoAllocation no_allocations_please;

-  ReplacingVisitor visitor(original, substitution);
+  ReplacingVisitor visitor(*original, *substitution);

// Iterate over all roots. Stack frames may have pointer into original code,
   // so temporary replace the pointers with offset numbers
@@ -1066,8 +1075,8 @@

   if (IsJSFunctionCode(shared_info->code())) {
     Handle<Code> code = compile_info_wrapper.GetFunctionCode();
-    ReplaceCodeObject(shared_info->code(), *code);
- Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo();
+    ReplaceCodeObject(Handle<Code>(shared_info->code()), code);
+ Handle<Object> code_scope_info = compile_info_wrapper.GetCodeScopeInfo();
     if (code_scope_info->IsFixedArray()) {
       shared_info->set_scope_info(ScopeInfo::cast(*code_scope_info));
     }
@@ -1309,7 +1318,7 @@
// on stack (it is safe to substitute the code object on stack, because
       // we only change the structure of rinfo and leave instructions
       // untouched).
-      ReplaceCodeObject(info->code(), *patched_code);
+      ReplaceCodeObject(Handle<Code>(info->code()), patched_code);
     }
   }

=======================================
--- /trunk/src/profile-generator.cc     Wed Jun 27 04:12:38 2012
+++ /trunk/src/profile-generator.cc     Tue Jul  3 03:03:19 2012
@@ -2182,16 +2182,31 @@
       switch (descs->GetType(i)) {
         case FIELD: {
           int index = descs->GetFieldIndex(i);
+
+          String* k = descs->GetKey(i);
           if (index < js_obj->map()->inobject_properties()) {
-            SetPropertyReference(
-                js_obj, entry,
-                descs->GetKey(i), js_obj->InObjectPropertyAt(index),
-                NULL,
-                js_obj->GetInObjectPropertyOffset(index));
+            Object* value = js_obj->InObjectPropertyAt(index);
+            if (k != heap_->hidden_symbol()) {
+              SetPropertyReference(
+                  js_obj, entry,
+                  k, value,
+                  NULL,
+                  js_obj->GetInObjectPropertyOffset(index));
+            } else {
+              TagObject(value, "(hidden properties)");
+              SetInternalReference(
+                  js_obj, entry,
+                  "hidden_properties", value,
+                  js_obj->GetInObjectPropertyOffset(index));
+            }
           } else {
-            SetPropertyReference(
-                js_obj, entry,
-                descs->GetKey(i), js_obj->FastPropertyAt(index));
+            Object* value = js_obj->FastPropertyAt(index);
+            if (k != heap_->hidden_symbol()) {
+              SetPropertyReference(js_obj, entry, k, value);
+            } else {
+              TagObject(value, "(hidden properties)");
+ SetInternalReference(js_obj, entry, "hidden_properties", value);
+            }
           }
           break;
         }
@@ -2237,7 +2252,7 @@
         Object* value = target->IsJSGlobalPropertyCell()
             ? JSGlobalPropertyCell::cast(target)->value()
             : target;
-        if (String::cast(k)->length() > 0) {
+        if (k != heap_->hidden_symbol()) {
           SetPropertyReference(js_obj, entry, String::cast(k), value);
         } else {
           TagObject(value, "(hidden properties)");
=======================================
--- /trunk/src/scopes.cc        Wed Jun 20 04:29:00 2012
+++ /trunk/src/scopes.cc        Tue Jul  3 03:03:19 2012
@@ -662,28 +662,36 @@
 }


-bool Scope::AllowsLazyCompilation() const {
-  return !force_eager_compilation_ &&
-         !TrivialDeclarationScopesBeforeWithScope();
+bool Scope::HasLazyCompilableOuterContext() const {
+  Scope* outer = outer_scope_;
+  if (outer == NULL) return true;
+  // There are several reasons that prevent lazy compilation:
+  // - This scope is inside a with scope and all declaration scopes between
+  //   them have empty contexts. Such declaration scopes become invisible
+  //   during scope info deserialization.
+  // - This scope is inside a strict eval scope with variables that are
+  //   potentially context allocated in an artificial function scope that
+  //   is not deserialized correctly.
+  outer = outer->DeclarationScope();
+  bool found_non_trivial_declarations = false;
+ for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) {
+    if (scope->is_eval_scope()) return false;
+ if (scope->is_with_scope() && !found_non_trivial_declarations) return false;
+    if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) {
+      found_non_trivial_declarations = true;
+    }
+  }
+  return true;
 }


-bool Scope::AllowsLazyCompilationWithoutContext() const {
-  return !force_eager_compilation_ && HasTrivialOuterContext();
+bool Scope::AllowsLazyCompilation() const {
+  return !force_eager_compilation_ && HasLazyCompilableOuterContext();
 }


-bool Scope::TrivialDeclarationScopesBeforeWithScope() const {
-  Scope* outer = outer_scope_;
-  if (outer == NULL) return false;
-  outer = outer->DeclarationScope();
-  while (outer != NULL) {
-    if (outer->is_with_scope()) return true;
-    if (outer->is_declaration_scope() && outer->num_heap_slots() > 0)
-      return false;
-    outer = outer->outer_scope_;
-  }
-  return false;
+bool Scope::AllowsLazyCompilationWithoutContext() const {
+  return !force_eager_compilation_ && HasTrivialOuterContext();
 }


=======================================
--- /trunk/src/scopes.h Wed Jun 20 04:29:00 2012
+++ /trunk/src/scopes.h Tue Jul  3 03:03:19 2012
@@ -380,10 +380,8 @@
   // True if the outer context of this scope is always the global context.
   bool HasTrivialOuterContext() const;

-  // True if this scope is inside a with scope and all declaration scopes
-  // between them have empty contexts. Such declaration scopes become
-  // invisible during scope info deserialization.
-  bool TrivialDeclarationScopesBeforeWithScope() const;
+  // True if the outer context allows lazy compilation of this scope.
+  bool HasLazyCompilableOuterContext() const;

   // The number of contexts between this and scope; zero if this == scope.
   int ContextChainLength(Scope* scope);
=======================================
--- /trunk/src/v8threads.cc     Thu Jan 19 07:36:35 2012
+++ /trunk/src/v8threads.cc     Tue Jul  3 03:03:19 2012
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -238,10 +238,16 @@
 ThreadState::ThreadState(ThreadManager* thread_manager)
     : id_(ThreadId::Invalid()),
       terminate_on_restore_(false),
+      data_(NULL),
       next_(this),
       previous_(this),
       thread_manager_(thread_manager) {
 }
+
+
+ThreadState::~ThreadState() {
+  DeleteArray<char>(data_);
+}


 void ThreadState::AllocateSpace() {
@@ -306,8 +312,19 @@

 ThreadManager::~ThreadManager() {
   delete mutex_;
-  delete free_anchor_;
-  delete in_use_anchor_;
+  DeleteThreadStateList(free_anchor_);
+  DeleteThreadStateList(in_use_anchor_);
+}
+
+
+void ThreadManager::DeleteThreadStateList(ThreadState* anchor) {
+  // The list starts and ends with the anchor.
+  for (ThreadState* current = anchor->next_; current != anchor;) {
+    ThreadState* next = current->next_;
+    delete current;
+    current = next;
+  }
+  delete anchor;
 }


=======================================
--- /trunk/src/v8threads.h      Tue Dec 13 00:07:27 2011
+++ /trunk/src/v8threads.h      Tue Jul  3 03:03:19 2012
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -57,6 +57,7 @@

  private:
   explicit ThreadState(ThreadManager* thread_manager);
+  ~ThreadState();

   void AllocateSpace();

@@ -114,6 +115,8 @@
   ThreadManager();
   ~ThreadManager();

+  void DeleteThreadStateList(ThreadState* anchor);
+
   void EagerlyArchiveThread();

   Mutex* mutex_;
=======================================
--- /trunk/src/version.cc       Fri Jun 29 08:15:45 2012
+++ /trunk/src/version.cc       Tue Jul  3 03:03:19 2012
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     12
-#define BUILD_NUMBER      6
+#define BUILD_NUMBER      7
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
=======================================
--- /trunk/test/cctest/cctest.status    Wed Jun 13 04:51:58 2012
+++ /trunk/test/cctest/cctest.status    Tue Jul  3 03:03:19 2012
@@ -54,7 +54,7 @@
 test-weakmaps/Shrinking: FAIL

##############################################################################
-[ $arch == arm ]
+[ $arch == arm || $arch == android ]

# We cannot assume that we can throw OutOfMemory exceptions in all situations. # Apparently our ARM box is in such a state. Skip the test as it also runs for
=======================================
--- /trunk/test/cctest/test-heap-profiler.cc    Wed Jun 27 04:12:38 2012
+++ /trunk/test/cctest/test-heap-profiler.cc    Tue Jul  3 03:03:19 2012
@@ -1449,6 +1449,36 @@
   CHECK_NE(NULL, setterFunction);
 }

+TEST(HiddenPropertiesFastCase) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  CompileRun(
+      "function C(x) { this.a = this; this.b = x; }\n"
+      "c = new C(2012);\n");
+  const v8::HeapSnapshot* snapshot =
+      v8::HeapProfiler::TakeSnapshot(v8_str("HiddenPropertiesFastCase1"));
+  const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+  const v8::HeapGraphNode* c =
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "c");
+  CHECK_NE(NULL, c);
+  const v8::HeapGraphNode* hidden_props =
+      GetProperty(c, v8::HeapGraphEdge::kInternal, "hidden_properties");
+  CHECK_EQ(NULL, hidden_props);
+
+  v8::Handle<v8::Value> cHandle = env->Global()->Get(v8::String::New("c"));
+  CHECK(!cHandle.IsEmpty() && cHandle->IsObject());
+  cHandle->ToObject()->GetIdentityHash();
+
+  snapshot = v8::HeapProfiler::TakeSnapshot(
+      v8_str("HiddenPropertiesFastCase2"));
+  global = GetGlobalObject(snapshot);
+  c = GetProperty(global, v8::HeapGraphEdge::kProperty, "c");
+  CHECK_NE(NULL, c);
+  hidden_props = GetProperty(c, v8::HeapGraphEdge::kInternal,
+      "hidden_properties");
+  CHECK_NE(NULL, hidden_props);
+}

 bool HasWeakEdge(const v8::HeapGraphNode* node) {
   for (int i = 0; i < node->GetChildrenCount(); ++i) {
=======================================
--- /trunk/test/cctest/testcfg.py       Fri May 11 08:02:09 2012
+++ /trunk/test/cctest/testcfg.py       Tue Jul  3 03:03:19 2012
@@ -93,7 +93,8 @@
       if utils.IsWindows():
         executable += '.exe'
       executable = join(self.context.buildspace, executable)
-    output = test.Execute([executable, '--list'], self.context)
+    full_command = self.context.processor([executable, '--list'])
+    output = test.Execute(full_command, self.context)
     if output.exit_code != 0:
       print output.stdout
       print output.stderr
=======================================
--- /trunk/test/mjsunit/external-array.js       Fri Jun 29 08:15:45 2012
+++ /trunk/test/mjsunit/external-array.js       Tue Jul  3 03:03:19 2012
@@ -540,3 +540,28 @@
 assertThrows(function(){ a.subarray.call({}, 0) });
 assertThrows(function(){ a.subarray.call([], 0) });
 assertThrows(function(){ a.subarray.call(a) });
+
+
+// Call constructors directly as functions, and through .call and .apply
+
+b = ArrayBuffer(100)
+a = Int8Array(b, 5, 77)
+assertInstance(b, ArrayBuffer)
+assertInstance(a, Int8Array)
+assertSame(b, a.buffer)
+assertEquals(5, a.byteOffset)
+assertEquals(77, a.byteLength)
+b = ArrayBuffer.call(null, 10)
+a = Uint16Array.call(null, b, 2, 4)
+assertInstance(b, ArrayBuffer)
+assertInstance(a, Uint16Array)
+assertSame(b, a.buffer)
+assertEquals(2, a.byteOffset)
+assertEquals(8, a.byteLength)
+b = ArrayBuffer.apply(null, [1000])
+a = Float32Array.apply(null, [b, 128, 1])
+assertInstance(b, ArrayBuffer)
+assertInstance(a, Float32Array)
+assertSame(b, a.buffer)
+assertEquals(128, a.byteOffset)
+assertEquals(4, a.byteLength)
=======================================
--- /trunk/test/mjsunit/mjsunit.status  Wed Jun 27 04:12:38 2012
+++ /trunk/test/mjsunit/mjsunit.status  Tue Jul  3 03:03:19 2012
@@ -49,28 +49,27 @@
##############################################################################
 # This one uses a built-in that's only present in debug mode. It takes
 # too long to run in debug mode on ARM and MIPS.
-fuzz-natives: PASS, SKIP if ($mode == release || $arch == arm || $arch == mips)
-
-big-object-literal: PASS, SKIP if ($arch == arm)
+fuzz-natives: PASS, SKIP if ($mode == release || $arch == arm || $arch == android || $arch == mips)
+
+big-object-literal: PASS, SKIP if ($arch == arm || $arch == android)

 # Issue 488: this test sometimes times out.
 array-constructor: PASS || TIMEOUT

 # Very slow on ARM and MIPS, contains no architecture dependent code.
-unicode-case-overoptimization: PASS, TIMEOUT if ($arch == arm || $arch == mips) +unicode-case-overoptimization: PASS, TIMEOUT if ($arch == arm || $arch == android || $arch == mips)

# Test Crankshaft compilation time. Expected to take too long in debug mode.
 regress/regress-1969: PASS, SKIP if $mode == debug

##############################################################################
-[ $isolates ]
-
 # This test sets the umask on a per-process basis and hence cannot be
 # used in multi-threaded runs.
-d8-os: SKIP
+# On android there is no /tmp directory.
+d8-os: PASS, SKIP if ($isolates || $arch == android)

##############################################################################
-[ $arch == arm ]
+[ $arch == arm || $arch == android ]

 # Slow tests which times out in debug mode.
 try: PASS, SKIP if $mode == debug
=======================================
--- /trunk/tools/test-wrapper-gypbuild.py       Thu Jun 28 08:04:22 2012
+++ /trunk/tools/test-wrapper-gypbuild.py       Tue Jul  3 03:03:19 2012
@@ -148,7 +148,7 @@
       print "Unknown mode %s" % mode
       return False
   for arch in options.arch:
-    if not arch in ['ia32', 'x64', 'arm', 'mips']:
+    if not arch in ['ia32', 'x64', 'arm', 'mips', 'android']:
       print "Unknown architecture %s" % arch
       return False
   if options.buildbot:
=======================================
--- /trunk/tools/test.py        Wed Jun 13 04:51:58 2012
+++ /trunk/tools/test.py        Tue Jul  3 03:03:19 2012
@@ -140,9 +140,9 @@
   parts = []
   for part in command:
     if ' ' in part:
-      # Escape spaces.  We may need to escape more characters for this
-      # to work properly.
-      parts.append('"%s"' % part)
+ # Escape spaces and double quotes. We may need to escape more characters
+      # for this to work properly.
+      parts.append('"%s"' % part.replace('"', '\\"'))
     else:
       parts.append(part)
   return " ".join(parts)
@@ -1283,7 +1283,7 @@
     options.scons_flags.append("arch=" + options.arch)
   # Simulators are slow, therefore allow a longer default timeout.
   if options.timeout == -1:
-    if options.arch == 'arm' or options.arch == 'mips':
+    if options.arch in ['android', 'arm', 'mips']:
       options.timeout = 2 * TIMEOUT_DEFAULT;
     else:
       options.timeout = TIMEOUT_DEFAULT;

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to