Version 3.30.29 (based on e634bdb290cb3761b9335d1bf7ec016fb3ebdbd5)
Cr-Commit-Position: refs/heads/candidates@{#25075}
git-svn-id: https://v8.googlecode.com/svn/trunk@25075 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc
index f4358ea..1dd9c16 100644
--- a/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/src/compiler/ia32/instruction-selector-ia32.cc
@@ -648,10 +648,9 @@
void InstructionSelector::VisitInt32MulHigh(Node* node) {
IA32OperandGenerator g(this);
- InstructionOperand* temps[] = {g.TempRegister(eax)};
Emit(kIA32ImulHigh, g.DefineAsFixed(node, edx),
- g.UseFixed(node->InputAt(0), eax), g.UseUniqueRegister(node->InputAt(1)),
- arraysize(temps), temps);
+ g.UseFixed(node->InputAt(0), eax),
+ g.UseUniqueRegister(node->InputAt(1)));
}
@@ -679,11 +678,9 @@
static inline void VisitMod(InstructionSelector* selector, Node* node,
ArchOpcode opcode) {
IA32OperandGenerator g(selector);
- InstructionOperand* temps[] = {g.TempRegister(eax), g.TempRegister(edx)};
- size_t temp_count = arraysize(temps);
selector->Emit(opcode, g.DefineAsFixed(node, edx),
g.UseFixed(node->InputAt(0), eax),
- g.UseUnique(node->InputAt(1)), temp_count, temps);
+ g.UseUnique(node->InputAt(1)));
}
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index 994a638..6b32258 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -252,7 +252,7 @@
redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {}
GenericGraphVisit::Control Post(Node* node) {
- if (node->op()->ValueOutputCount() > 0 && !NodeProperties::IsTyped(node)) {
+ if (node->op()->ValueOutputCount() > 0) {
Bounds bounds = TypeNode(node);
NodeProperties::SetBounds(node, bounds);
// Remember incompletely typed nodes for least fixpoint iteration.
@@ -291,33 +291,64 @@
class Typer::WidenVisitor : public Typer::Visitor {
public:
- explicit WidenVisitor(Typer* typer) : Visitor(typer) {}
+ explicit WidenVisitor(Typer* typer)
+ : Visitor(typer),
+ local_zone_(zone()->isolate()),
+ enabled_(graph()->NodeCount(), true, &local_zone_),
+ queue_(&local_zone_) {}
- GenericGraphVisit::Control Pre(Node* node) {
- if (node->op()->ValueOutputCount() > 0) {
- Bounds previous = BoundsOrNone(node);
- Bounds current = TypeNode(node);
+ void Run(NodeSet* nodes) {
+ // Queue all the roots.
+ for (Node* node : *nodes) {
+ Queue(node);
+ }
- // Speed up termination in the presence of range types:
- current.upper = Weaken(current.upper, previous.upper);
- current.lower = Weaken(current.lower, previous.lower);
+ while (!queue_.empty()) {
+ Node* node = queue_.front();
+ queue_.pop();
- DCHECK(previous.lower->Is(current.lower));
- DCHECK(previous.upper->Is(current.upper));
+ if (node->op()->ValueOutputCount() > 0) {
+ // Enable future queuing (and thus re-typing) of this node.
+ enabled_[node->id()] = true;
- NodeProperties::SetBounds(node, current);
- // Stop when nothing changed (but allow re-entry in case it does later).
- return previous.Narrows(current) && current.Narrows(previous)
- ? GenericGraphVisit::DEFER
- : GenericGraphVisit::REENTER;
- } else {
- return GenericGraphVisit::SKIP;
+ // Compute the new type.
+ Bounds previous = BoundsOrNone(node);
+ Bounds current = TypeNode(node);
+
+ // Speed up termination in the presence of range types:
+ current.upper = Weaken(current.upper, previous.upper);
+ current.lower = Weaken(current.lower, previous.lower);
+
+ // Types should not get less precise.
+ DCHECK(previous.lower->Is(current.lower));
+ DCHECK(previous.upper->Is(current.upper));
+
+ NodeProperties::SetBounds(node, current);
+ // If something changed, push all uses into the queue.
+ if (!(previous.Narrows(current) && current.Narrows(previous))) {
+ for (Node* use : node->uses()) {
+ Queue(use);
+ }
+ }
+ }
+ // If there is no value output, we deliberately leave the node disabled
+ // for queuing - there is no need to type it.
}
}
- GenericGraphVisit::Control Post(Node* node) {
- return GenericGraphVisit::REENTER;
+ void Queue(Node* node) {
+ // If the node is enabled for queuing, push it to the queue and disable it
+ // (to avoid queuing it multiple times).
+ if (enabled_[node->id()]) {
+ queue_.push(node);
+ enabled_[node->id()] = false;
+ }
}
+
+ private:
+ Zone local_zone_;
+ BoolVector enabled_;
+ ZoneQueue<Node*> queue_;
};
@@ -326,9 +357,7 @@
graph_->VisitNodeInputsFromEnd(&typing);
// Find least fixpoint.
WidenVisitor widen(this);
- for (NodeSetIter it = typing.redo.begin(); it != typing.redo.end(); ++it) {
- graph_->VisitNodeUsesFrom(*it, &widen);
- }
+ widen.Run(&typing.redo);
}
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc
index f49f8bf..432b21c 100644
--- a/src/compiler/x64/instruction-selector-x64.cc
+++ b/src/compiler/x64/instruction-selector-x64.cc
@@ -420,10 +420,9 @@
void InstructionSelector::VisitInt32MulHigh(Node* node) {
X64OperandGenerator g(this);
- InstructionOperand* temps[] = {g.TempRegister(rax)};
Emit(kX64ImulHigh32, g.DefineAsFixed(node, rdx),
- g.UseFixed(node->InputAt(0), rax), g.UseUniqueRegister(node->InputAt(1)),
- arraysize(temps), temps);
+ g.UseFixed(node->InputAt(0), rax),
+ g.UseUniqueRegister(node->InputAt(1)));
}
@@ -460,10 +459,9 @@
static void VisitMod(InstructionSelector* selector, Node* node,
ArchOpcode opcode) {
X64OperandGenerator g(selector);
- InstructionOperand* temps[] = {g.TempRegister(rax), g.TempRegister(rdx)};
- selector->Emit(
- opcode, g.DefineAsFixed(node, rdx), g.UseFixed(node->InputAt(0), rax),
- g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
+ selector->Emit(opcode, g.DefineAsFixed(node, rdx),
+ g.UseFixed(node->InputAt(0), rax),
+ g.UseUniqueRegister(node->InputAt(1)));
}
diff --git a/src/globals.h b/src/globals.h
index 03eb99e..4ea06b2 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -376,7 +376,6 @@
CELL_SPACE, // Only and all cell objects.
PROPERTY_CELL_SPACE, // Only and all global property cell objects.
LO_SPACE, // Promoted large objects.
- INVALID_SPACE, // Only used in AllocationResult to signal success.
FIRST_SPACE = NEW_SPACE,
LAST_SPACE = LO_SPACE,
diff --git a/src/heap/heap-inl.h b/src/heap/heap-inl.h
index 9e3421e..48e928d 100644
--- a/src/heap/heap-inl.h
+++ b/src/heap/heap-inl.h
@@ -458,8 +458,6 @@
case PROPERTY_CELL_SPACE:
case LO_SPACE:
return false;
- case INVALID_SPACE:
- break;
}
UNREACHABLE();
return false;
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 93e00d2..5c8cd45 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -4545,8 +4545,6 @@
return property_cell_space_->Contains(addr);
case LO_SPACE:
return lo_space_->SlowContains(addr);
- case INVALID_SPACE:
- break;
}
UNREACHABLE();
return false;
diff --git a/src/heap/spaces.h b/src/heap/spaces.h
index 1944464..ef294b2 100644
--- a/src/heap/spaces.h
+++ b/src/heap/spaces.h
@@ -1614,16 +1614,19 @@
public:
// Implicit constructor from Object*.
AllocationResult(Object* object) // NOLINT
- : object_(object),
- retry_space_(INVALID_SPACE) {}
+ : object_(object) {
+ // AllocationResults can't return Smis, which are used to represent
+ // failure and the space to retry in.
+ CHECK(!object->IsSmi());
+ }
- AllocationResult() : object_(NULL), retry_space_(INVALID_SPACE) {}
+ AllocationResult() : object_(Smi::FromInt(NEW_SPACE)) {}
static inline AllocationResult Retry(AllocationSpace space = NEW_SPACE) {
return AllocationResult(space);
}
- inline bool IsRetry() { return retry_space_ != INVALID_SPACE; }
+ inline bool IsRetry() { return object_->IsSmi(); }
template <typename T>
bool To(T** obj) {
@@ -1639,18 +1642,20 @@
AllocationSpace RetrySpace() {
DCHECK(IsRetry());
- return retry_space_;
+ return static_cast<AllocationSpace>(Smi::cast(object_)->value());
}
private:
explicit AllocationResult(AllocationSpace space)
- : object_(NULL), retry_space_(space) {}
+ : object_(Smi::FromInt(static_cast<int>(space))) {}
Object* object_;
- AllocationSpace retry_space_;
};
+STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize);
+
+
class PagedSpace : public Space {
public:
// Creates a space with a maximum capacity, and an id.
diff --git a/src/serialize.cc b/src/serialize.cc
index df62adb..6347943 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -1903,7 +1903,7 @@
}
}
UNREACHABLE();
- return INVALID_SPACE;
+ return FIRST_SPACE;
}
diff --git a/src/serialize.h b/src/serialize.h
index 9c56118..d7a6c7f 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -296,7 +296,7 @@
// No reservation for large object space necessary.
static const int kNumberOfPreallocatedSpaces = LO_SPACE;
- static const int kNumberOfSpaces = INVALID_SPACE;
+ static const int kNumberOfSpaces = LAST_SPACE + 1;
protected:
// Where the pointed-to object can be found:
diff --git a/src/third_party/fdlibm/fdlibm.js b/src/third_party/fdlibm/fdlibm.js
index 08c6f5e..b52f1de 100644
--- a/src/third_party/fdlibm/fdlibm.js
+++ b/src/third_party/fdlibm/fdlibm.js
@@ -267,7 +267,7 @@
}
}
}
- if (ix >= 0x3fe59429) { // |x| > .6744
+ if (ix >= 0x3fe59428) { // |x| > .6744
if (x < 0) {
x = -x;
y = -y;
diff --git a/src/version.cc b/src/version.cc
index 3be87c9..2f8ab0d 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION 3
#define MINOR_VERSION 30
-#define BUILD_NUMBER 28
+#define BUILD_NUMBER 29
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/test/cctest/test-alloc.cc b/test/cctest/test-alloc.cc
index d647a31..54d516e 100644
--- a/test/cctest/test-alloc.cc
+++ b/test/cctest/test-alloc.cc
@@ -86,7 +86,7 @@
Builtins::kIllegal)).ToObjectChecked();
// Return success.
- return Smi::FromInt(42);
+ return heap->true_value();
}
@@ -100,7 +100,7 @@
v8::Handle<v8::Context> env = v8::Context::New(CcTest::isolate());
env->Enter();
Handle<Object> o = Test();
- CHECK(o->IsSmi() && Smi::cast(*o)->value() == 42);
+ CHECK(o->IsTrue());
env->Exit();
}
@@ -162,7 +162,7 @@
// Call the accessor through JavaScript.
v8::Handle<v8::Value> result = v8::Script::Compile(
v8::String::NewFromUtf8(CcTest::isolate(), "(new Foo).get"))->Run();
- CHECK_EQ(42, result->Int32Value());
+ CHECK_EQ(true, result->BooleanValue());
env->Exit();
}
diff --git a/test/mjsunit/compiler/regress-register-allocator2.js b/test/mjsunit/compiler/regress-register-allocator2.js
new file mode 100644
index 0000000..06e0c49
--- /dev/null
+++ b/test/mjsunit/compiler/regress-register-allocator2.js
@@ -0,0 +1,17 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function f() {
+ var x = 0;
+ var y = 0;
+ x ^= undefined;
+ assertEquals(x /= 1);
+ assertEquals(NaN, y %= 1);
+ assertEquals(y = 1);
+ f();
+ y = -2;
+ assertEquals(x >>= 1);
+ assertEquals(0, ((y+(y+(y+((y^(x%5))+y)))+(y+y))>>y)+y);
+}
+try { f(); } catch (e) {}
diff --git a/test/mjsunit/sin-cos.js b/test/mjsunit/sin-cos.js
index 71fae20..fb6f858 100644
--- a/test/mjsunit/sin-cos.js
+++ b/test/mjsunit/sin-cos.js
@@ -227,6 +227,8 @@
assertEquals(0.8211418015898941, Math.tan(11/16));
assertEquals(-0.8211418015898941, Math.tan(-11/16));
assertEquals(0.41421356237309503, Math.tan(Math.PI / 8));
+// crbug/427468
+assertEquals(0.7993357819992383, Math.tan(0.6743358));
// Tests for Math.sin.
assertEquals(0.479425538604203, Math.sin(0.5));
diff --git a/tools/push-to-trunk/auto_push.py b/tools/push-to-trunk/auto_push.py
index cec1489..b0f1b26 100755
--- a/tools/push-to-trunk/auto_push.py
+++ b/tools/push-to-trunk/auto_push.py
@@ -118,6 +118,8 @@
args.extend(["--svn-config", self._options.svn_config])
if self._options.vc_interface:
args.extend(["--vc-interface", self._options.vc_interface])
+ if self._options.work_dir:
+ args.extend(["--work-dir", self._options.work_dir])
# TODO(machenbach): Update the script before calling it.
if self._options.push:
diff --git a/tools/push-to-trunk/auto_roll.py b/tools/push-to-trunk/auto_roll.py
index 2cca070..00f45e0 100755
--- a/tools/push-to-trunk/auto_roll.py
+++ b/tools/push-to-trunk/auto_roll.py
@@ -99,6 +99,8 @@
"--sheriff", "--googlers-mapping", self._options.googlers_mapping])
if self._options.dry_run:
args.extend(["--dry-run"])
+ if self._options.work_dir:
+ args.extend(["--work-dir", self._options.work_dir])
self._side_effect_handler.Call(chromium_roll.ChromiumRoll().Run, args)
diff --git a/tools/push-to-trunk/common_includes.py b/tools/push-to-trunk/common_includes.py
index a555500..e95d555 100644
--- a/tools/push-to-trunk/common_includes.py
+++ b/tools/push-to-trunk/common_includes.py
@@ -48,7 +48,7 @@
VERSION_FILE = os.path.join("src", "version.cc")
# V8 base directory.
-DEFAULT_CWD = os.path.dirname(
+V8_BASE = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
@@ -408,7 +408,7 @@
# is the case for all automated merge and push commits - also no title is
# the prefix of another title).
commit = None
- for wait_interval in [3, 7, 15, 35, 35]:
+ for wait_interval in [3, 7, 15, 35, 45, 60]:
self.step.Git("fetch")
commit = self.step.GitLog(n=1, format="%H", grep=message, branch=remote)
if commit:
@@ -470,7 +470,8 @@
self.vc.InjectStep(self)
# The testing configuration might set a different default cwd.
- self.default_cwd = self._config.get("DEFAULT_CWD") or DEFAULT_CWD
+ self.default_cwd = (self._config.get("DEFAULT_CWD") or
+ os.path.join(self._options.work_dir, "v8"))
assert self._number >= 0
assert self._config is not None
@@ -744,6 +745,19 @@
cwd=self._options.svn)
+class BootstrapStep(Step):
+ MESSAGE = "Bootstapping v8 checkout."
+
+ def RunStep(self):
+ if os.path.realpath(self.default_cwd) == os.path.realpath(V8_BASE):
+ self.Die("Can't use v8 checkout with calling script as work checkout.")
+ # Directory containing the working v8 checkout.
+ if not os.path.exists(self._options.work_dir):
+ os.makedirs(self._options.work_dir)
+ if not os.path.exists(self.default_cwd):
+ self.Command("fetch", "v8", cwd=self._options.work_dir)
+
+
class UploadStep(Step):
MESSAGE = "Upload for code review."
@@ -859,6 +873,9 @@
parser.add_argument("--vc-interface",
help=("Choose VC interface out of git_svn|"
"git_read_svn_write."))
+ parser.add_argument("--work-dir",
+ help=("Location where to bootstrap a working v8 "
+ "checkout."))
self._PrepareOptions(parser)
if args is None: # pragma: no cover
@@ -898,6 +915,8 @@
if not options.vc_interface:
options.vc_interface = "git_read_svn_write"
+ if not options.work_dir:
+ options.work_dir = "/tmp/v8-release-scripts-work-dir"
return options
def RunSteps(self, step_classes, args=None):
@@ -910,7 +929,7 @@
os.remove(state_file)
steps = []
- for (number, step_class) in enumerate(step_classes):
+ for (number, step_class) in enumerate([BootstrapStep] + step_classes):
steps.append(MakeStep(step_class, number, self._state, self._config,
options, self._side_effect_handler))
for step in steps[options.step:]:
diff --git a/tools/push-to-trunk/test_scripts.py b/tools/push-to-trunk/test_scripts.py
index d92c388..6eeb323 100644
--- a/tools/push-to-trunk/test_scripts.py
+++ b/tools/push-to-trunk/test_scripts.py
@@ -694,6 +694,21 @@
commit_msg = """Line with "quotation marks"."""
self._TestSquashCommits(change_log, commit_msg)
+ def testBootstrapper(self):
+ work_dir = self.MakeEmptyTempDirectory()
+ class FakeScript(ScriptsBase):
+ def _Steps(self):
+ return []
+
+ # Use the test configuration without the fake testing default work dir.
+ fake_config = dict(TEST_CONFIG)
+ del(fake_config["DEFAULT_CWD"])
+
+ self.Expect([
+ Cmd("fetch v8", "", cwd=work_dir),
+ ])
+ FakeScript(fake_config, self).Run(["--work-dir", work_dir])
+
def _PushToTrunk(self, force=False, manual=False):
TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
@@ -967,7 +982,8 @@
args = ["-a", "author@chromium.org", "--revision", "push_hash",
"--vc-interface", "git", "-f", "-r", "reviewer@chromium.org",
- "--svn", svn_root, "--svn-config", "[CONFIG_DIR]"]
+ "--svn", svn_root, "--svn-config", "[CONFIG_DIR]",
+ "--work-dir", TEST_CONFIG["DEFAULT_CWD"]]
PushToTrunk(TEST_CONFIG, self).Run(args)
cl = FileToText(TEST_CONFIG["CHANGELOG_FILE"])
@@ -1318,7 +1334,7 @@
lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
# Test that state recovery after restarting the script works.
- args += ["-s", "3"]
+ args += ["-s", "4"]
MergeToBranch(TEST_CONFIG, self).Run(args)
def testMergeToBranchNewGit(self):
@@ -1459,7 +1475,7 @@
lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
# Test that state recovery after restarting the script works.
- args += ["-s", "3"]
+ args += ["-s", "4"]
MergeToBranch(TEST_CONFIG, self).Run(args)
def testReleases(self):