Revision: 16096
Author: [email protected]
Date: Wed Aug 7 02:48:48 2013
Log: Version 3.20.14.1: Rollback of r16071 in trunk branch.
Un-revert "Implement simple effect typing for variables" and "Handle switch
effects"
[email protected]
Review URL: https://codereview.chromium.org/22546003
http://code.google.com/p/v8/source/detail?r=16096
Deleted:
/trunk/src/effects.h
Modified:
/trunk/src/ast.h
/trunk/src/splay-tree-inl.h
/trunk/src/splay-tree.h
/trunk/src/types.h
/trunk/src/typing.cc
/trunk/src/typing.h
/trunk/src/version.cc
/trunk/src/zone-inl.h
/trunk/src/zone.h
/trunk/test/cctest/test-global-handles.cc
/trunk/tools/gyp/v8.gyp
=======================================
--- /trunk/src/effects.h Wed Aug 7 02:20:40 2013
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef V8_EFFECTS_H_
-#define V8_EFFECTS_H_
-
-#include "v8.h"
-
-#include "types.h"
-
-namespace v8 {
-namespace internal {
-
-
-// A simple struct to represent (write) effects. A write is represented as
a
-// modification of type bounds (e.g. of a variable).
-//
-// An effect can either be definite, if the write is known to have taken
place,
-// or 'possible', if it was optional. The difference is relevant when
composing
-// effects.
-//
-// There are two ways to compose effects: sequentially (they happen one
after
-// the other) or alternatively (either one or the other happens). A
definite
-// effect cancels out any previous effect upon sequencing. A possible
effect
-// merges into a previous effect, i.e., type bounds are merged. Alternative
-// composition always merges bounds. It yields a possible effect if at
least
-// one was only possible.
-struct Effect {
- enum Modality { POSSIBLE, DEFINITE };
-
- Modality modality;
- Bounds bounds;
-
- Effect() {}
- Effect(Bounds b, Modality m = DEFINITE) : modality(m), bounds(b) {}
-
- // The unknown effect.
- static Effect Unknown(Isolate* isolate) {
- return Effect(Bounds::Unbounded(isolate), POSSIBLE);
- }
-
- static Effect Forget(Isolate* isolate) {
- return Effect(Bounds::Unbounded(isolate), DEFINITE);
- }
-
- // Sequential composition, as in 'e1; e2'.
- static Effect Seq(Effect e1, Effect e2, Isolate* isolate) {
- if (e2.modality == DEFINITE) return e2;
- return Effect(Bounds::Either(e1.bounds, e2.bounds, isolate),
e1.modality);
- }
-
- // Alternative composition, as in 'cond ? e1 : e2'.
- static Effect Alt(Effect e1, Effect e2, Isolate* isolate) {
- return Effect(
- Bounds::Either(e1.bounds, e2.bounds, isolate),
- e1.modality == POSSIBLE ? POSSIBLE : e2.modality);
- }
-};
-
-
-// Classes encapsulating sets of effects on variables.
-//
-// Effects maps variables to effects and supports sequential and
alternative
-// composition.
-//
-// NestedEffects is an incremental representation that supports persistence
-// through functional extension. It represents the map as an adjoin of a
list
-// of maps, whose tail can be shared.
-//
-// Both classes provide similar interfaces, implemented in parts through
the
-// EffectsMixin below (using sandwich style, to work around the style
guide's
-// MI restriction).
-//
-// We also (ab)use Effects/NestedEffects as a representation for abstract
-// store typings. In that case, only definite effects are of interest.
-
-template<class Var, class Base, class Effects>
-class EffectsMixin: public Base {
- public:
- explicit EffectsMixin(Zone* zone) : Base(zone) {}
-
- Effect Lookup(Var var) {
- Locator locator;
- return this->Find(var, &locator)
- ? locator.value() : Effect::Unknown(Base::isolate());
- }
-
- Bounds LookupBounds(Var var) {
- Effect effect = Lookup(var);
- return effect.modality == Effect::DEFINITE
- ? effect.bounds : Bounds::Unbounded(Base::isolate());
- }
-
- // Sequential composition.
- void Seq(Var var, Effect effect) {
- Locator locator;
- if (!this->Insert(var, &locator)) {
- effect = Effect::Seq(locator.value(), effect, Base::isolate());
- }
- locator.set_value(effect);
- }
-
- void Seq(Effects that) {
- SeqMerger<EffectsMixin> merge = { *this };
- that.ForEach(&merge);
- }
-
- // Alternative composition.
- void Alt(Var var, Effect effect) {
- Locator locator;
- if (!this->Insert(var, &locator)) {
- effect = Effect::Alt(locator.value(), effect, Base::isolate());
- }
- locator.set_value(effect);
- }
-
- void Alt(Effects that) {
- AltWeakener<EffectsMixin> weaken = { *this, that };
- this->ForEach(&weaken);
- AltMerger<EffectsMixin> merge = { *this };
- that.ForEach(&merge);
- }
-
- // Invalidation.
- void Forget() {
- Overrider override = {
- Effect::Forget(Base::isolate()), Effects(Base::zone()) };
- this->ForEach(&override);
- Seq(override.effects);
- }
-
- protected:
- typedef typename Base::Locator Locator;
-
- template<class Self>
- struct SeqMerger {
- void Call(Var var, Effect effect) { self.Seq(var, effect); }
- Self self;
- };
-
- template<class Self>
- struct AltMerger {
- void Call(Var var, Effect effect) { self.Alt(var, effect); }
- Self self;
- };
-
- template<class Self>
- struct AltWeakener {
- void Call(Var var, Effect effect) {
- if (effect.modality == Effect::DEFINITE && !other.Contains(var)) {
- effect.modality = Effect::POSSIBLE;
- Locator locator;
- self.Insert(var, &locator);
- locator.set_value(effect);
- }
- }
- Self self;
- Effects other;
- };
-
- struct Overrider {
- void Call(Var var, Effect effect) { effects.Seq(var, new_effect); }
- Effect new_effect;
- Effects effects;
- };
-};
-
-
-template<class Var, Var kNoVar> class Effects;
-template<class Var, Var kNoVar> class NestedEffectsBase;
-
-template<class Var, Var kNoVar>
-class EffectsBase {
- public:
- explicit EffectsBase(Zone* zone) : map_(new(zone) Mapping(zone)) {}
-
- bool IsEmpty() { return map_->is_empty(); }
-
- protected:
- friend class NestedEffectsBase<Var, kNoVar>;
- friend class
- EffectsMixin<Var, NestedEffectsBase<Var, kNoVar>, Effects<Var,
kNoVar> >;
-
- Zone* zone() { return map_->allocator().zone(); }
- Isolate* isolate() { return zone()->isolate(); }
-
- struct SplayTreeConfig {
- typedef Var Key;
- typedef Effect Value;
- static const Var kNoKey = kNoVar;
- static Effect NoValue() { return Effect(); }
- static int Compare(int x, int y) { return y - x; }
- };
- typedef ZoneSplayTree<SplayTreeConfig> Mapping;
- typedef typename Mapping::Locator Locator;
-
- bool Contains(Var var) {
- ASSERT(var != kNoVar);
- return map_->Contains(var);
- }
- bool Find(Var var, Locator* locator) {
- ASSERT(var != kNoVar);
- return map_->Find(var, locator);
- }
- bool Insert(Var var, Locator* locator) {
- ASSERT(var != kNoVar);
- return map_->Insert(var, locator);
- }
-
- template<class Callback>
- void ForEach(Callback* callback) {
- return map_->ForEach(callback);
- }
-
- private:
- Mapping* map_;
-};
-
-template<class Var, Var kNoVar>
-const Var EffectsBase<Var, kNoVar>::SplayTreeConfig::kNoKey;
-
-template<class Var, Var kNoVar>
-class Effects: public
- EffectsMixin<Var, EffectsBase<Var, kNoVar>, Effects<Var, kNoVar> > {
- public:
- explicit Effects(Zone* zone)
- : EffectsMixin<Var, EffectsBase<Var, kNoVar>, Effects<Var, kNoVar>
(zone)
- {}
-};
-
-
-template<class Var, Var kNoVar>
-class NestedEffectsBase {
- public:
- explicit NestedEffectsBase(Zone* zone) : node_(new(zone) Node(zone)) {}
-
- template<class Callback>
- void ForEach(Callback* callback) {
- if (node_->previous)
NestedEffectsBase(node_->previous).ForEach(callback);
- node_->effects.ForEach(callback);
- }
-
- Effects<Var, kNoVar> Top() { return node_->effects; }
-
- bool IsEmpty() {
- for (Node* node = node_; node != NULL; node = node->previous) {
- if (!node->effects.IsEmpty()) return false;
- }
- return true;
- }
-
- protected:
- typedef typename EffectsBase<Var, kNoVar>::Locator Locator;
-
- Zone* zone() { return node_->zone; }
- Isolate* isolate() { return zone()->isolate(); }
-
- void push() { node_ = new(node_->zone) Node(node_->zone, node_); }
- void pop() { node_ = node_->previous; }
- bool is_empty() { return node_ == NULL; }
-
- bool Contains(Var var) {
- ASSERT(var != kNoVar);
- for (Node* node = node_; node != NULL; node = node->previous) {
- if (node->effects.Contains(var)) return true;
- }
- return false;
- }
-
- bool Find(Var var, Locator* locator) {
- ASSERT(var != kNoVar);
- for (Node* node = node_; node != NULL; node = node->previous) {
- if (node->effects.Find(var, locator)) return true;
- }
- return false;
- }
-
- bool Insert(Var var, Locator* locator);
-
- private:
- struct Node: ZoneObject {
- Zone* zone;
- Effects<Var, kNoVar> effects;
- Node* previous;
- explicit Node(Zone* zone, Node* previous = NULL)
- : zone(zone), effects(zone), previous(previous) {}
- };
-
- explicit NestedEffectsBase(Node* node) : node_(node) {}
-
- Node* node_;
-};
-
-
-template<class Var, Var kNoVar>
-bool NestedEffectsBase<Var, kNoVar>::Insert(Var var, Locator* locator) {
- ASSERT(var != kNoVar);
- if (!node_->effects.Insert(var, locator)) return false;
- Locator shadowed;
- for (Node* node = node_->previous; node != NULL; node = node->previous) {
- if (node->effects.Find(var, &shadowed)) {
- // Initialize with shadowed entry.
- locator->set_value(shadowed.value());
- return false;
- }
- }
- return true;
-}
-
-
-template<class Var, Var kNoVar>
-class NestedEffects: public
- EffectsMixin<Var, NestedEffectsBase<Var, kNoVar>, Effects<Var, kNoVar>
{
- public:
- explicit NestedEffects(Zone* zone) :
- EffectsMixin<Var, NestedEffectsBase<Var, kNoVar>, Effects<Var,
kNoVar> >(
- zone) {}
-
- // Create an extension of the current effect set. The current set should
not
- // be modified while the extension is in use.
- NestedEffects Push() {
- NestedEffects result = *this;
- result.push();
- return result;
- }
-
- NestedEffects Pop() {
- NestedEffects result = *this;
- result.pop();
- ASSERT(!this->is_empty());
- return result;
- }
-};
-
-} } // namespace v8::internal
-
-#endif // V8_EFFECTS_H_
=======================================
--- /trunk/src/ast.h Wed Aug 7 02:20:40 2013
+++ /trunk/src/ast.h Wed Aug 7 02:48:48 2013
@@ -259,7 +259,6 @@
Statement() : statement_pos_(RelocInfo::kNoPosition) {}
bool IsEmpty() { return AsEmptyStatement() != NULL; }
- virtual bool IsJump() const { return false; }
void set_statement_pos(int statement_pos) { statement_pos_ =
statement_pos; }
int statement_pos() const { return statement_pos_; }
@@ -389,7 +388,7 @@
protected:
explicit Expression(Isolate* isolate)
- : bounds_(Bounds::Unbounded(isolate)),
+ : bounds_(Type::None(), Type::Any(), isolate),
id_(GetNextId(isolate)),
test_id_(GetNextId(isolate)) {}
void set_to_boolean_types(byte types) { to_boolean_types_ = types; }
@@ -458,11 +457,6 @@
ZoneList<Statement*>* statements() { return &statements_; }
bool is_initializer_block() const { return is_initializer_block_; }
-
- virtual bool IsJump() const {
- return !statements_.is_empty() && statements_.last()->IsJump()
- && labels() == NULL; // Good enough as an approximation...
- }
Scope* scope() const { return scope_; }
void set_scope(Scope* scope) { scope_ = scope; }
@@ -1014,7 +1008,6 @@
void set_expression(Expression* e) { expression_ = e; }
Expression* expression() const { return expression_; }
- virtual bool IsJump() const { return expression_->IsThrow(); }
protected:
explicit ExpressionStatement(Expression* expression)
@@ -1025,16 +1018,7 @@
};
-class JumpStatement: public Statement {
- public:
- virtual bool IsJump() const { return true; }
-
- protected:
- JumpStatement() {}
-};
-
-
-class ContinueStatement: public JumpStatement {
+class ContinueStatement: public Statement {
public:
DECLARE_NODE_TYPE(ContinueStatement)
@@ -1049,7 +1033,7 @@
};
-class BreakStatement: public JumpStatement {
+class BreakStatement: public Statement {
public:
DECLARE_NODE_TYPE(BreakStatement)
@@ -1064,7 +1048,7 @@
};
-class ReturnStatement: public JumpStatement {
+class ReturnStatement: public Statement {
public:
DECLARE_NODE_TYPE(ReturnStatement)
@@ -1182,11 +1166,6 @@
Expression* condition() const { return condition_; }
Statement* then_statement() const { return then_statement_; }
Statement* else_statement() const { return else_statement_; }
-
- virtual bool IsJump() const {
- return HasThenStatement() && then_statement()->IsJump()
- && HasElseStatement() && else_statement()->IsJump();
- }
BailoutId IfId() const { return if_id_; }
BailoutId ThenId() const { return then_id_; }
=======================================
--- /trunk/src/splay-tree-inl.h Wed Aug 7 02:20:40 2013
+++ /trunk/src/splay-tree-inl.h Wed Aug 7 02:48:48 2013
@@ -88,12 +88,6 @@
Splay(key);
return Config::Compare(key, root_->key_) == 0;
}
-
-
-template<typename Config, class Allocator>
-bool SplayTree<Config, Allocator>::Contains(const Key& key) {
- return FindInternal(key);
-}
template<typename Config, class Allocator>
@@ -299,10 +293,9 @@
template <typename Config, class Allocator> template <class Callback>
void SplayTree<Config, Allocator>::ForEachNode(Callback* callback) {
- if (root_ == NULL) return;
// Pre-allocate some space for tiny trees.
List<Node*, Allocator> nodes_to_visit(10, allocator_);
- nodes_to_visit.Add(root_, allocator_);
+ if (root_ != NULL) nodes_to_visit.Add(root_, allocator_);
int pos = 0;
while (pos < nodes_to_visit.length()) {
Node* node = nodes_to_visit[pos++];
=======================================
--- /trunk/src/splay-tree.h Wed Aug 7 02:20:40 2013
+++ /trunk/src/splay-tree.h Wed Aug 7 02:48:48 2013
@@ -39,9 +39,9 @@
//
// typedef Key: the key type
// typedef Value: the value type
-// static const Key kNoKey: the dummy key used when no key is set
-// static Value kNoValue(): the dummy value used to initialize nodes
-// static int (Compare)(Key& a, Key& b) -> {-1, 0, 1}: comparison
function
+// static const kNoKey: the dummy key used when no key is set
+// static const kNoValue: the dummy value used to initialize nodes
+// int (Compare)(Key& a, Key& b) -> {-1, 0, 1}: comparison function
//
// The tree is also parameterized by an allocation policy
// (Allocator). The policy is used for allocating lists in the C free
@@ -73,11 +73,6 @@
INLINE(void operator delete(void* p, AllocationPolicy policy)) {
UNREACHABLE();
}
-
- AllocationPolicy allocator() { return allocator_; }
-
- // Checks if there is a mapping for the key.
- bool Contains(const Key& key);
// Inserts the given key in this tree with the given value. Returns
// true if a node was inserted, otherwise false. If found the locator
@@ -108,9 +103,6 @@
// Remove the node with the given key from the tree.
bool Remove(const Key& key);
-
- // Remove all keys from the tree.
- void Clear() { ResetRoot(); }
bool is_empty() { return root_ == NULL; }
=======================================
--- /trunk/src/types.h Wed Aug 7 02:20:40 2013
+++ /trunk/src/types.h Wed Aug 7 02:48:48 2013
@@ -302,11 +302,6 @@
Bounds(Type* l, Type* u, Isolate* isl) : lower(l, isl), upper(u, isl) {}
explicit Bounds(Handle<Type> t) : lower(t), upper(t) {}
Bounds(Type* t, Isolate* isl) : lower(t, isl), upper(t, isl) {}
-
- // Unrestricted bounds.
- static Bounds Unbounded(Isolate* isl) {
- return Bounds(Type::None(), Type::Any(), isl);
- }
// Meet: both b1 and b2 are known to hold.
static Bounds Both(Bounds b1, Bounds b2, Isolate* isl) {
=======================================
--- /trunk/src/typing.cc Wed Aug 7 02:20:40 2013
+++ /trunk/src/typing.cc Wed Aug 7 02:48:48 2013
@@ -40,8 +40,7 @@
Handle<Code>(info->closure()->shared()->code()),
Handle<Context>(info->closure()->context()->native_context()),
info->isolate(),
- info->zone()),
- store_(info->zone()) {
+ info->zone()) {
InitializeAstVisitor();
}
@@ -80,16 +79,12 @@
for (int i = 0; i < stmts->length(); ++i) {
Statement* stmt = stmts->at(i);
RECURSE(Visit(stmt));
- if (stmt->IsJump()) break;
}
}
void AstTyper::VisitBlock(Block* stmt) {
RECURSE(VisitStatements(stmt->statements()));
- if (stmt->labels() != NULL) {
- store_.Forget(); // Control may transfer here via 'break l'.
- }
}
@@ -103,41 +98,30 @@
void AstTyper::VisitIfStatement(IfStatement* stmt) {
- // Collect type feedback.
+ RECURSE(Visit(stmt->condition()));
+ RECURSE(Visit(stmt->then_statement()));
+ RECURSE(Visit(stmt->else_statement()));
+
if (!stmt->condition()->ToBooleanIsTrue() &&
!stmt->condition()->ToBooleanIsFalse()) {
stmt->condition()->RecordToBooleanTypeFeedback(oracle());
}
-
- RECURSE(Visit(stmt->condition()));
- Effects then_effects = EnterEffects();
- RECURSE(Visit(stmt->then_statement()));
- ExitEffects();
- Effects else_effects = EnterEffects();
- RECURSE(Visit(stmt->else_statement()));
- ExitEffects();
- then_effects.Alt(else_effects);
- store_.Seq(then_effects);
}
void AstTyper::VisitContinueStatement(ContinueStatement* stmt) {
- // TODO(rossberg): is it worth having a non-termination effect?
}
void AstTyper::VisitBreakStatement(BreakStatement* stmt) {
- // TODO(rossberg): is it worth having a non-termination effect?
}
void AstTyper::VisitReturnStatement(ReturnStatement* stmt) {
- // Collect type feedback.
+ RECURSE(Visit(stmt->expression()));
+
// TODO(rossberg): we only need this for inlining into test contexts...
stmt->expression()->RecordToBooleanTypeFeedback(oracle());
-
- RECURSE(Visit(stmt->expression()));
- // TODO(rossberg): is it worth having a non-termination effect?
}
@@ -149,18 +133,14 @@
void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) {
RECURSE(Visit(stmt->tag()));
-
ZoneList<CaseClause*>* clauses = stmt->cases();
SwitchStatement::SwitchType switch_type = stmt->switch_type();
- Effects local_effects(zone());
- bool complex_effects = false; // True for label effects or fall-through.
-
for (int i = 0; i < clauses->length(); ++i) {
CaseClause* clause = clauses->at(i);
- Effects clause_effects = EnterEffects();
-
if (!clause->is_default()) {
Expression* label = clause->label();
+ RECURSE(Visit(label));
+
SwitchStatement::SwitchType label_switch_type =
label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH :
label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH :
@@ -169,32 +149,13 @@
switch_type = label_switch_type;
else if (switch_type != label_switch_type)
switch_type = SwitchStatement::GENERIC_SWITCH;
-
- RECURSE(Visit(label));
- if (!clause_effects.IsEmpty()) complex_effects = true;
}
-
- ZoneList<Statement*>* stmts = clause->statements();
- RECURSE(VisitStatements(stmts));
- ExitEffects();
- if (stmts->is_empty() || stmts->last()->IsJump()) {
- local_effects.Alt(clause_effects);
- } else {
- complex_effects = true;
- }
+ RECURSE(VisitStatements(clause->statements()));
}
-
- if (complex_effects) {
- store_.Forget(); // Reached this in unknown state.
- } else {
- store_.Seq(local_effects);
- }
-
if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
switch_type = SwitchStatement::GENERIC_SWITCH;
stmt->set_switch_type(switch_type);
- // Collect type feedback.
// TODO(rossberg): can we eliminate this special case and extra loop?
if (switch_type == SwitchStatement::SMI_SWITCH) {
for (int i = 0; i < clauses->length(); ++i) {
@@ -207,31 +168,22 @@
void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
- // Collect type feedback.
+ RECURSE(Visit(stmt->body()));
+ RECURSE(Visit(stmt->cond()));
+
if (!stmt->cond()->ToBooleanIsTrue()) {
stmt->cond()->RecordToBooleanTypeFeedback(oracle());
}
-
- // TODO(rossberg): refine the unconditional Forget (here and elsewhere)
by
- // computing the set of variables assigned in only some of the origins
of the
- // control transfer (such as the loop body here).
- store_.Forget(); // Control may transfer here via looping or 'continue'.
- RECURSE(Visit(stmt->body()));
- RECURSE(Visit(stmt->cond()));
- store_.Forget(); // Control may transfer here via 'break'.
}
void AstTyper::VisitWhileStatement(WhileStatement* stmt) {
- // Collect type feedback.
+ RECURSE(Visit(stmt->cond()));
+ RECURSE(Visit(stmt->body()));
+
if (!stmt->cond()->ToBooleanIsTrue()) {
stmt->cond()->RecordToBooleanTypeFeedback(oracle());
}
-
- store_.Forget(); // Control may transfer here via looping or 'continue'.
- RECURSE(Visit(stmt->cond()));
- RECURSE(Visit(stmt->body()));
- store_.Forget(); // Control may transfer here via termination
or 'break'.
}
@@ -239,65 +191,45 @@
if (stmt->init() != NULL) {
RECURSE(Visit(stmt->init()));
}
- store_.Forget(); // Control may transfer here via looping.
if (stmt->cond() != NULL) {
- // Collect type feedback.
+ RECURSE(Visit(stmt->cond()));
+
stmt->cond()->RecordToBooleanTypeFeedback(oracle());
-
- RECURSE(Visit(stmt->cond()));
}
RECURSE(Visit(stmt->body()));
- store_.Forget(); // Control may transfer here via 'continue'.
if (stmt->next() != NULL) {
RECURSE(Visit(stmt->next()));
}
- store_.Forget(); // Control may transfer here via termination
or 'break'.
}
void AstTyper::VisitForInStatement(ForInStatement* stmt) {
- // Collect type feedback.
- stmt->RecordTypeFeedback(oracle());
-
RECURSE(Visit(stmt->enumerable()));
- store_.Forget(); // Control may transfer here via looping or 'continue'.
RECURSE(Visit(stmt->body()));
- store_.Forget(); // Control may transfer here via 'break'.
+
+ stmt->RecordTypeFeedback(oracle());
}
void AstTyper::VisitForOfStatement(ForOfStatement* stmt) {
RECURSE(Visit(stmt->iterable()));
- store_.Forget(); // Control may transfer here via looping or 'continue'.
RECURSE(Visit(stmt->body()));
- store_.Forget(); // Control may transfer here via 'break'.
}
void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
- Effects try_effects = EnterEffects();
RECURSE(Visit(stmt->try_block()));
- ExitEffects();
- Effects catch_effects = EnterEffects();
- store_.Forget(); // Control may transfer here via 'throw'.
RECURSE(Visit(stmt->catch_block()));
- ExitEffects();
- try_effects.Alt(catch_effects);
- store_.Seq(try_effects);
- // At this point, only variables that were reassigned in the catch block
are
- // still remembered.
}
void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
RECURSE(Visit(stmt->try_block()));
- store_.Forget(); // Control may transfer here via 'throw'.
RECURSE(Visit(stmt->finally_block()));
}
void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
- store_.Forget(); // May do whatever.
}
@@ -310,18 +242,11 @@
void AstTyper::VisitConditional(Conditional* expr) {
- // Collect type feedback.
- expr->condition()->RecordToBooleanTypeFeedback(oracle());
-
RECURSE(Visit(expr->condition()));
- Effects then_effects = EnterEffects();
RECURSE(Visit(expr->then_expression()));
- ExitEffects();
- Effects else_effects = EnterEffects();
RECURSE(Visit(expr->else_expression()));
- ExitEffects();
- then_effects.Alt(else_effects);
- store_.Seq(then_effects);
+
+ expr->condition()->RecordToBooleanTypeFeedback(oracle());
NarrowType(expr, Bounds::Either(
expr->then_expression()->bounds(),
@@ -330,10 +255,7 @@
void AstTyper::VisitVariableProxy(VariableProxy* expr) {
- Variable* var = expr->var();
- if (var->IsStackAllocated()) {
- NarrowType(expr, store_.LookupBounds(variable_index(var)));
- }
+ // TODO(rossberg): typing of variables
}
@@ -352,8 +274,8 @@
ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
for (int i = 0; i < properties->length(); ++i) {
ObjectLiteral::Property* prop = properties->at(i);
+ RECURSE(Visit(prop->value()));
- // Collect type feedback.
if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL &&
!CompileTimeValue::IsCompileTimeValue(prop->value())) ||
prop->kind() == ObjectLiteral::Property::COMPUTED) {
@@ -361,8 +283,6 @@
prop->RecordTypeFeedback(oracle());
}
}
-
- RECURSE(Visit(prop->value()));
}
NarrowType(expr, Bounds(Type::Object(), isolate_));
@@ -383,7 +303,8 @@
void AstTyper::VisitAssignment(Assignment* expr) {
// TODO(rossberg): Can we clean this up?
if (expr->is_compound()) {
- // Collect type feedback.
+ RECURSE(Visit(expr->binary_operation()));
+
Expression* target = expr->target();
Property* prop = target->AsProperty();
if (prop != NULL) {
@@ -392,26 +313,19 @@
expr->RecordTypeFeedback(oracle(), zone());
}
}
-
- RECURSE(Visit(expr->binary_operation()));
NarrowType(expr, expr->binary_operation()->bounds());
} else {
- // Collect type feedback.
- if (expr->target()->IsProperty()) {
+ RECURSE(Visit(expr->target()));
+ RECURSE(Visit(expr->value()));
+
+ if (expr->target()->AsProperty()) {
expr->RecordTypeFeedback(oracle(), zone());
}
-
- RECURSE(Visit(expr->target()));
- RECURSE(Visit(expr->value()));
NarrowType(expr, expr->value()->bounds());
}
-
- VariableProxy* proxy = expr->target()->AsVariableProxy();
- if (proxy != NULL && proxy->var()->IsStackAllocated()) {
- store_.Seq(variable_index(proxy->var()), Effect(expr->bounds()));
- }
+ // TODO(rossberg): handle target variables
}
@@ -419,40 +333,28 @@
RECURSE(Visit(expr->generator_object()));
RECURSE(Visit(expr->expression()));
- // We don't know anything about the result type.
+ // We don't know anything about the type.
}
void AstTyper::VisitThrow(Throw* expr) {
RECURSE(Visit(expr->exception()));
- // TODO(rossberg): is it worth having a non-termination effect?
NarrowType(expr, Bounds(Type::None(), isolate_));
}
void AstTyper::VisitProperty(Property* expr) {
- // Collect type feedback.
- expr->RecordTypeFeedback(oracle(), zone());
-
RECURSE(Visit(expr->obj()));
RECURSE(Visit(expr->key()));
- // We don't know anything about the result type.
+ expr->RecordTypeFeedback(oracle(), zone());
+
+ // We don't know anything about the type.
}
void AstTyper::VisitCall(Call* expr) {
- // Collect type feedback.
- Expression* callee = expr->expression();
- Property* prop = callee->AsProperty();
- if (prop != NULL) {
- if (prop->key()->IsPropertyName())
- expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
- } else {
- expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION);
- }
-
RECURSE(Visit(expr->expression()));
ZoneList<Expression*>* args = expr->arguments();
for (int i = 0; i < args->length(); ++i) {
@@ -460,19 +362,20 @@
RECURSE(Visit(arg));
}
- VariableProxy* proxy = expr->expression()->AsVariableProxy();
- if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
- store_.Forget(); // Eval could do whatever to local variables.
+ Expression* callee = expr->expression();
+ Property* prop = callee->AsProperty();
+ if (prop != NULL) {
+ if (prop->key()->IsPropertyName())
+ expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
+ } else {
+ expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION);
}
- // We don't know anything about the result type.
+ // We don't know anything about the type.
}
void AstTyper::VisitCallNew(CallNew* expr) {
- // Collect type feedback.
- expr->RecordTypeFeedback(oracle());
-
RECURSE(Visit(expr->expression()));
ZoneList<Expression*>* args = expr->arguments();
for (int i = 0; i < args->length(); ++i) {
@@ -480,7 +383,9 @@
RECURSE(Visit(arg));
}
- // We don't know anything about the result type.
+ expr->RecordTypeFeedback(oracle());
+
+ // We don't know anything about the type.
}
@@ -491,18 +396,18 @@
RECURSE(Visit(arg));
}
- // We don't know anything about the result type.
+ // We don't know anything about the type.
}
void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
+ RECURSE(Visit(expr->expression()));
+
// Collect type feedback.
if (expr->op() == Token::NOT) {
// TODO(rossberg): only do in test or value context.
expr->expression()->RecordToBooleanTypeFeedback(oracle());
}
-
- RECURSE(Visit(expr->expression()));
switch (expr->op()) {
case Token::NOT:
@@ -522,25 +427,22 @@
void AstTyper::VisitCountOperation(CountOperation* expr) {
- // Collect type feedback.
+ RECURSE(Visit(expr->expression()));
+
expr->RecordTypeFeedback(oracle(), zone());
Property* prop = expr->expression()->AsProperty();
if (prop != NULL) {
prop->RecordTypeFeedback(oracle(), zone());
}
-
- RECURSE(Visit(expr->expression()));
NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_));
-
- VariableProxy* proxy = expr->expression()->AsVariableProxy();
- if (proxy != NULL && proxy->var()->IsStackAllocated()) {
- store_.Seq(variable_index(proxy->var()), Effect(expr->bounds()));
- }
}
void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
+ RECURSE(Visit(expr->left()));
+ RECURSE(Visit(expr->right()));
+
// Collect type feedback.
Handle<Type> type, left_type, right_type;
Maybe<int> fixed_right_arg;
@@ -556,29 +458,15 @@
switch (expr->op()) {
case Token::COMMA:
- RECURSE(Visit(expr->left()));
- RECURSE(Visit(expr->right()));
NarrowType(expr, expr->right()->bounds());
break;
case Token::OR:
- case Token::AND: {
- Effects left_effects = EnterEffects();
- RECURSE(Visit(expr->left()));
- ExitEffects();
- Effects right_effects = EnterEffects();
- RECURSE(Visit(expr->right()));
- ExitEffects();
- left_effects.Alt(right_effects);
- store_.Seq(left_effects);
-
+ case Token::AND:
NarrowType(expr, Bounds::Either(
expr->left()->bounds(), expr->right()->bounds(), isolate_));
break;
- }
case Token::BIT_OR:
case Token::BIT_AND: {
- RECURSE(Visit(expr->left()));
- RECURSE(Visit(expr->right()));
Type* upper = Type::Union(
expr->left()->bounds().upper, expr->right()->bounds().upper);
if (!upper->Is(Type::Signed32())) upper = Type::Signed32();
@@ -588,18 +476,12 @@
case Token::BIT_XOR:
case Token::SHL:
case Token::SAR:
- RECURSE(Visit(expr->left()));
- RECURSE(Visit(expr->right()));
NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_));
break;
case Token::SHR:
- RECURSE(Visit(expr->left()));
- RECURSE(Visit(expr->right()));
NarrowType(expr, Bounds(Type::Smi(), Type::Unsigned32(), isolate_));
break;
case Token::ADD: {
- RECURSE(Visit(expr->left()));
- RECURSE(Visit(expr->right()));
Bounds l = expr->left()->bounds();
Bounds r = expr->right()->bounds();
Type* lower =
@@ -619,8 +501,6 @@
case Token::MUL:
case Token::DIV:
case Token::MOD:
- RECURSE(Visit(expr->left()));
- RECURSE(Visit(expr->right()));
NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_));
break;
default:
@@ -630,6 +510,9 @@
void AstTyper::VisitCompareOperation(CompareOperation* expr) {
+ RECURSE(Visit(expr->left()));
+ RECURSE(Visit(expr->right()));
+
// Collect type feedback.
Handle<Type> left_type, right_type, combined_type;
oracle()->CompareType(expr->CompareOperationFeedbackId(),
@@ -638,9 +521,6 @@
NarrowLowerType(expr->right(), right_type);
expr->set_combined_type(combined_type);
- RECURSE(Visit(expr->left()));
- RECURSE(Visit(expr->right()));
-
NarrowType(expr, Bounds(Type::Boolean(), isolate_));
}
=======================================
--- /trunk/src/typing.h Wed Aug 7 02:20:40 2013
+++ /trunk/src/typing.h Wed Aug 7 02:48:48 2013
@@ -35,7 +35,6 @@
#include "compiler.h"
#include "type-info.h"
#include "types.h"
-#include "effects.h"
#include "zone.h"
#include "scopes.h"
@@ -58,13 +57,8 @@
private:
explicit AstTyper(CompilationInfo* info);
- static const int kNoVar = INT_MIN;
- typedef v8::internal::Effects<int, kNoVar> Effects;
- typedef v8::internal::NestedEffects<int, kNoVar> Store;
-
CompilationInfo* info_;
TypeFeedbackOracle oracle_;
- Store store_;
TypeFeedbackOracle* oracle() { return &oracle_; }
Zone* zone() const { return info_->zone(); }
@@ -75,17 +69,6 @@
void NarrowLowerType(Expression* e, Handle<Type> t) {
e->set_bounds(Bounds::NarrowLower(e->bounds(), t, isolate_));
}
-
- Effects EnterEffects() {
- store_ = store_.Push();
- return store_.Top();
- }
- void ExitEffects() { store_ = store_.Pop(); }
-
- int variable_index(Variable* var) {
- return var->IsStackLocal() ? var->index() :
- var->IsParameter() ? -var->index() : kNoVar;
- }
void VisitDeclarations(ZoneList<Declaration*>* declarations);
void VisitStatements(ZoneList<Statement*>* statements);
=======================================
--- /trunk/src/version.cc Wed Aug 7 02:20:40 2013
+++ /trunk/src/version.cc Wed Aug 7 02:48:48 2013
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 20
#define BUILD_NUMBER 14
-#define PATCH_LEVEL 0
+#define PATCH_LEVEL 1
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
=======================================
--- /trunk/src/zone-inl.h Wed Aug 7 02:20:40 2013
+++ /trunk/src/zone-inl.h Wed Aug 7 02:48:48 2013
@@ -107,12 +107,6 @@
void* ZoneList<T>::operator new(size_t size, Zone* zone) {
return zone->New(static_cast<int>(size));
}
-
-
-template <typename T>
-void* ZoneSplayTree<T>::operator new(size_t size, Zone* zone) {
- return zone->New(static_cast<int>(size));
-}
} } // namespace v8::internal
=======================================
--- /trunk/src/zone.h Wed Aug 7 02:20:40 2013
+++ /trunk/src/zone.h Wed Aug 7 02:48:48 2013
@@ -177,7 +177,6 @@
explicit ZoneAllocationPolicy(Zone* zone) : zone_(zone) { }
INLINE(void* New(size_t size));
INLINE(static void Delete(void *pointer)) { }
- Zone* zone() { return zone_; }
private:
Zone* zone_;
=======================================
--- /trunk/test/cctest/test-global-handles.cc Wed Aug 7 02:20:40 2013
+++ /trunk/test/cctest/test-global-handles.cc Wed Aug 7 02:48:48 2013
@@ -418,7 +418,7 @@
int32_t offset = ++weak_offset_;
object->Set(7, v8::Integer::New(offset, isolate));
v8::Persistent<v8::Object> persistent(isolate, object);
- persistent.MakeWeak(this, WeakCallback);
+ persistent.MakeWeak(isolate, this, WeakCallback);
persistent.MarkIndependent();
Object** location = v8::Utils::OpenPersistent(persistent).location();
bool inserted =
=======================================
--- /trunk/tools/gyp/v8.gyp Wed Aug 7 02:20:40 2013
+++ /trunk/tools/gyp/v8.gyp Wed Aug 7 02:48:48 2013
@@ -290,7 +290,6 @@
'../../src/double.h',
'../../src/dtoa.cc',
'../../src/dtoa.h',
- '../../src/effects.h',
'../../src/elements-kind.cc',
'../../src/elements-kind.h',
'../../src/elements.cc',
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.