Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(629)

Unified Diff: src/ast.cc

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ast.h ('k') | src/ast-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ast.cc
diff --git a/src/ast.cc b/src/ast.cc
index 47900afaf4d0588b3847f7ea273cf11d807a54b9..f69db803eb1174f9e68f11dae6d2274f554e6667 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -28,16 +28,14 @@
#include "v8.h"
#include "ast.h"
+#include "jump-target-inl.h"
#include "parser.h"
#include "scopes.h"
#include "string-stream.h"
-#include "ast-inl.h"
-#include "jump-target-inl.h"
namespace v8 {
namespace internal {
-
AstSentinels::AstSentinels()
: this_proxy_(true),
identifier_proxy_(false),
@@ -50,6 +48,8 @@ AstSentinels::AstSentinels()
// ----------------------------------------------------------------------------
// All the Accept member functions for each syntax tree node type.
+void Slot::Accept(AstVisitor* v) { v->VisitSlot(this); }
+
#define DECL_ACCEPT(type) \
void type::Accept(AstVisitor* v) { v->Visit##type(this); }
AST_NODE_LIST(DECL_ACCEPT)
@@ -117,6 +117,29 @@ void VariableProxy::BindTo(Variable* var) {
}
+Assignment::Assignment(Token::Value op,
+ Expression* target,
+ Expression* value,
+ int pos)
+ : op_(op),
+ target_(target),
+ value_(value),
+ pos_(pos),
+ compound_bailout_id_(kNoNumber),
+ block_start_(false),
+ block_end_(false),
+ is_monomorphic_(false),
+ receiver_types_(NULL) {
+ ASSERT(Token::IsAssignmentOp(op));
+ binary_operation_ = is_compound()
+ ? new BinaryOperation(binary_op(), target, value, pos + 1)
+ : NULL;
+ if (is_compound()) {
+ compound_bailout_id_ = GetNextId();
+ }
+}
+
+
Token::Value Assignment::binary_op() const {
switch (op_) {
case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
@@ -141,6 +164,12 @@ bool FunctionLiteral::AllowsLazyCompilation() {
}
+bool FunctionLiteral::AllowOptimize() {
+ // We can't deal with heap-allocated locals.
+ return scope()->num_heap_slots() == 0;
+}
+
+
ObjectLiteral::Property::Property(Literal* key, Expression* value) {
emit_store_ = true;
key_ = key;
@@ -375,6 +404,265 @@ BinaryOperation::BinaryOperation(Assignment* assignment) {
// ----------------------------------------------------------------------------
+// Inlining support
+
+bool Block::IsInlineable() const {
+ const int count = statements_.length();
+ for (int i = 0; i < count; ++i) {
+ if (!statements_[i]->IsInlineable()) return false;
+ }
+ return true;
+}
+
+
+bool ExpressionStatement::IsInlineable() const {
+ return expression()->IsInlineable();
+}
+
+
+bool IfStatement::IsInlineable() const {
+ return condition()->IsInlineable() && then_statement()->IsInlineable() &&
+ else_statement()->IsInlineable();
+}
+
+
+bool ReturnStatement::IsInlineable() const {
+ return expression()->IsInlineable();
+}
+
+
+bool Conditional::IsInlineable() const {
+ return condition()->IsInlineable() && then_expression()->IsInlineable() &&
+ else_expression()->IsInlineable();
+}
+
+
+bool VariableProxy::IsInlineable() const {
+ return var()->is_global() || var()->IsStackAllocated();
+}
+
+
+bool Assignment::IsInlineable() const {
+ return target()->IsInlineable() && value()->IsInlineable();
+}
+
+
+bool Property::IsInlineable() const {
+ return obj()->IsInlineable() && key()->IsInlineable();
+}
+
+
+bool Call::IsInlineable() const {
+ if (!expression()->IsInlineable()) return false;
+ const int count = arguments()->length();
+ for (int i = 0; i < count; ++i) {
+ if (!arguments()->at(i)->IsInlineable()) return false;
+ }
+ return true;
+}
+
+
+bool CallNew::IsInlineable() const {
+ if (!expression()->IsInlineable()) return false;
+ const int count = arguments()->length();
+ for (int i = 0; i < count; ++i) {
+ if (!arguments()->at(i)->IsInlineable()) return false;
+ }
+ return true;
+}
+
+
+bool CallRuntime::IsInlineable() const {
+ const int count = arguments()->length();
+ for (int i = 0; i < count; ++i) {
+ if (!arguments()->at(i)->IsInlineable()) return false;
+ }
+ return true;
+}
+
+
+bool UnaryOperation::IsInlineable() const {
+ return expression()->IsInlineable();
+}
+
+
+bool BinaryOperation::IsInlineable() const {
+ return left()->IsInlineable() && right()->IsInlineable();
+}
+
+
+bool CompareOperation::IsInlineable() const {
+ return left()->IsInlineable() && right()->IsInlineable();
+}
+
+
+bool CompareToNull::IsInlineable() const {
+ return expression()->IsInlineable();
+}
+
+
+bool CountOperation::IsInlineable() const {
+ return expression()->IsInlineable();
+}
+
+
+// ----------------------------------------------------------------------------
+// Recording of type feedback
+
+void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
+ // Record type feedback from the oracle in the AST.
+ is_monomorphic_ = oracle->LoadIsMonomorphic(this);
+ if (key()->IsPropertyName()) {
+ if (oracle->LoadIsBuiltin(this, Builtins::LoadIC_ArrayLength)) {
+ is_array_length_ = true;
+ } else {
+ Literal* lit_key = key()->AsLiteral();
+ ASSERT(lit_key != NULL && lit_key->handle()->IsString());
+ Handle<String> name = Handle<String>::cast(lit_key->handle());
+ ZoneMapList* types = oracle->LoadReceiverTypes(this, name);
+ receiver_types_ = types;
+ }
+ } else if (is_monomorphic_) {
+ monomorphic_receiver_type_ = oracle->LoadMonomorphicReceiverType(this);
+ }
+}
+
+
+void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
+ Property* prop = target()->AsProperty();
+ ASSERT(prop != NULL);
+ is_monomorphic_ = oracle->StoreIsMonomorphic(this);
+ if (prop->key()->IsPropertyName()) {
+ Literal* lit_key = prop->key()->AsLiteral();
+ ASSERT(lit_key != NULL && lit_key->handle()->IsString());
+ Handle<String> name = Handle<String>::cast(lit_key->handle());
+ ZoneMapList* types = oracle->StoreReceiverTypes(this, name);
+ receiver_types_ = types;
+ } else if (is_monomorphic_) {
+ // Record receiver type for monomorphic keyed loads.
+ monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this);
+ }
+}
+
+
+void CaseClause::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
+ TypeInfo info = oracle->SwitchType(this);
+ if (info.IsSmi()) {
+ compare_type_ = SMI_ONLY;
+ } else if (info.IsNonPrimitive()) {
+ compare_type_ = OBJECT_ONLY;
+ } else {
+ ASSERT(compare_type_ == NONE);
+ }
+}
+
+
+static bool CallWithoutIC(Handle<JSFunction> target, int arity) {
+ if (target->NeedsArgumentsAdaption()) {
+ // If the number of formal parameters of the target function
+ // does not match the number of arguments we're passing, we
+ // don't want to deal with it.
+ return target->shared()->formal_parameter_count() == arity;
+ } else {
+ // If the target doesn't need arguments adaption, we can call
+ // it directly, but we avoid to do so if it has a custom call
+ // generator, because that is likely to generate better code.
+ return !target->shared()->HasCustomCallGenerator();
+ }
+}
+
+
+bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
+ holder_ = Handle<JSObject>::null();
+ while (true) {
+ LookupResult lookup;
+ type->LookupInDescriptors(NULL, *name, &lookup);
+ // If the function wasn't found directly in the map, we start
+ // looking upwards through the prototype chain.
+ if (!lookup.IsFound() && type->prototype()->IsJSObject()) {
+ holder_ = Handle<JSObject>(JSObject::cast(type->prototype()));
+ type = Handle<Map>(holder()->map());
+ } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) {
+ target_ = Handle<JSFunction>(lookup.GetConstantFunctionFromMap(*type));
+ return CallWithoutIC(target_, arguments()->length());
+ } else {
+ return false;
+ }
+ }
+}
+
+
+bool Call::ComputeGlobalTarget(Handle<GlobalObject> global,
+ Handle<String> name) {
+ target_ = Handle<JSFunction>::null();
+ cell_ = Handle<JSGlobalPropertyCell>::null();
+ LookupResult lookup;
+ global->Lookup(*name, &lookup);
+ if (lookup.IsProperty() && lookup.type() == NORMAL) {
+ cell_ = Handle<JSGlobalPropertyCell>(global->GetPropertyCell(&lookup));
+ if (cell_->value()->IsJSFunction()) {
+ Handle<JSFunction> candidate(JSFunction::cast(cell_->value()));
+ // If the function is in new space we assume it's more likely to
+ // change and thus prefer the general IC code.
+ if (!Isolate::Current()->heap()->InNewSpace(*candidate)
+ && CallWithoutIC(candidate, arguments()->length())) {
+ target_ = candidate;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
+ Property* property = expression()->AsProperty();
+ ASSERT(property != NULL);
+ // Specialize for the receiver types seen at runtime.
+ Literal* key = property->key()->AsLiteral();
+ ASSERT(key != NULL && key->handle()->IsString());
+ Handle<String> name = Handle<String>::cast(key->handle());
+ receiver_types_ = oracle->CallReceiverTypes(this, name);
+#ifdef DEBUG
+ if (FLAG_enable_slow_asserts) {
+ if (receiver_types_ != NULL) {
+ int length = receiver_types_->length();
+ for (int i = 0; i < length; i++) {
+ Handle<Map> map = receiver_types_->at(i);
+ ASSERT(!map.is_null() && *map != NULL);
+ }
+ }
+ }
+#endif
+ if (receiver_types_ != NULL && receiver_types_->length() > 0) {
+ Handle<Map> type = receiver_types_->at(0);
+ is_monomorphic_ = oracle->CallIsMonomorphic(this);
+ if (is_monomorphic_) is_monomorphic_ = ComputeTarget(type, name);
+ }
+}
+
+
+void BinaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
+ TypeInfo left = oracle->BinaryType(this, TypeFeedbackOracle::LEFT);
+ TypeInfo right = oracle->BinaryType(this, TypeFeedbackOracle::RIGHT);
+ is_smi_only_ = left.IsSmi() && right.IsSmi();
+}
+
+
+void CompareOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
+ TypeInfo left = oracle->CompareType(this, TypeFeedbackOracle::LEFT);
+ TypeInfo right = oracle->CompareType(this, TypeFeedbackOracle::RIGHT);
+ if (left.IsSmi() && right.IsSmi()) {
+ compare_type_ = SMI_ONLY;
+ } else if (left.IsNonPrimitive() && right.IsNonPrimitive()) {
+ compare_type_ = OBJECT_ONLY;
+ } else {
+ ASSERT(compare_type_ == NONE);
+ }
+}
+
+
+// ----------------------------------------------------------------------------
// Implementation of AstVisitor
bool AstVisitor::CheckStackOverflow() {
@@ -744,15 +1032,12 @@ RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes)
}
-WhileStatement::WhileStatement(ZoneStringList* labels)
- : IterationStatement(labels),
- cond_(NULL),
- may_have_function_literal_(true) {
-}
-
-
-CaseClause::CaseClause(Expression* label, ZoneList<Statement*>* statements)
- : label_(label), statements_(statements) {
-}
+CaseClause::CaseClause(Expression* label,
+ ZoneList<Statement*>* statements,
+ int pos)
+ : label_(label),
+ statements_(statements),
+ position_(pos),
+ compare_type_(NONE) {}
} } // namespace v8::internal
« no previous file with comments | « src/ast.h ('k') | src/ast-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698