Revision: 5560
Author: [email protected]
Date: Thu Sep 30 01:48:37 2010
Log: Introduce subclasses of class CompilationInfo.

It was a wart that we had three handle fields, exactly one of which
was non-null; and that we had three overloaded constructors.  Instead,
introduce subclasses and virtual methods.

Remove some unused fields from class CompilationInfo.

Review URL: http://codereview.chromium.org/3566003
http://code.google.com/p/v8/source/detail?r=5560

Modified:
 /branches/bleeding_edge/src/compiler.cc
 /branches/bleeding_edge/src/compiler.h
 /branches/bleeding_edge/src/handles.cc
 /branches/bleeding_edge/src/liveedit.cc

=======================================
--- /branches/bleeding_edge/src/compiler.cc     Thu Sep 23 01:27:51 2010
+++ /branches/bleeding_edge/src/compiler.cc     Thu Sep 30 01:48:37 2010
@@ -146,9 +146,10 @@
   bool is_json = (validate == Compiler::VALIDATE_JSON);
 #ifdef ENABLE_DEBUGGER_SUPPORT
   if (is_eval || is_json) {
-    script->set_compilation_type(
-        is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
- Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
+    Script::CompilationType compilation_type = is_json
+        ? Script::COMPILATION_TYPE_JSON
+        : Script::COMPILATION_TYPE_EVAL;
+    script->set_compilation_type(Smi::FromInt(compilation_type));
     // For eval scripts add information on the function from which eval was
     // called.
     if (is_eval) {
@@ -171,16 +172,16 @@
   ASSERT(is_eval || is_global);

   // Build AST.
+  EagerCompilationInfo info(script, is_eval);
   FunctionLiteral* lit =
       MakeAST(is_global, script, extension, pre_data, is_json);

-  LiveEditFunctionTracker live_edit_tracker(lit);
-
   // Check for parse errors.
   if (lit == NULL) {
     ASSERT(Top::has_pending_exception());
     return Handle<SharedFunctionInfo>::null();
   }
+  info.set_function(lit);

   // Measure how long it takes to do the compilation; only take the
   // rest of the function into account to avoid overlap with the
@@ -191,7 +192,7 @@
   HistogramTimerScope timer(rate);

   // Compile the code.
-  CompilationInfo info(lit, script, is_eval);
+  LiveEditFunctionTracker live_edit_tracker(lit);
   Handle<Code> code = MakeCode(context, &info);

   // Check for stack-overflow exceptions.
@@ -482,7 +483,8 @@
     // Generate code and return it.  The way that the compilation mode
     // is controlled by the command-line flags is described in
     // the static helper function MakeCode.
-    CompilationInfo info(literal, script, false);
+    EagerCompilationInfo info(script, false);
+    info.set_function(literal);

     bool is_run_once = literal->try_full_codegen();
     bool use_full = FLAG_full_compiler && !literal->contains_loops();
=======================================
--- /branches/bleeding_edge/src/compiler.h      Wed Sep 29 10:38:37 2010
+++ /branches/bleeding_edge/src/compiler.h      Thu Sep 30 01:48:37 2010
@@ -41,94 +41,109 @@
 // is constructed based on the resources available at compile-time.
 class CompilationInfo BASE_EMBEDDED {
  public:
-  // Lazy compilation of a JSFunction.
-  CompilationInfo(Handle<JSFunction> closure, int loop_nesting)
-      : closure_(closure),
-        function_(NULL),
-        is_eval_(false),
-        loop_nesting_(loop_nesting) {
-    ASSERT(!closure_.is_null() &&
-           shared_info_.is_null() &&
-           script_.is_null());
-  }
-
-  // Lazy compilation based on SharedFunctionInfo.
-  explicit CompilationInfo(Handle<SharedFunctionInfo> shared_info)
-      : shared_info_(shared_info),
-        function_(NULL),
-        is_eval_(false),
-        loop_nesting_(0) {
-    ASSERT(closure_.is_null() &&
-           !shared_info_.is_null() &&
-           script_.is_null());
+  virtual ~CompilationInfo() {}
+
+  // Dispatched behavior.
+  virtual Handle<SharedFunctionInfo> shared_info() const = 0;
+
+  virtual Handle<Script> script() const {
+    return Handle<Script>(Script::cast(shared_info()->script()));
   }

-  // Eager compilation.
- CompilationInfo(FunctionLiteral* literal, Handle<Script> script, bool is_eval)
-      : script_(script),
-        function_(literal),
-        is_eval_(is_eval),
-        loop_nesting_(0) {
-    ASSERT(closure_.is_null() &&
-           shared_info_.is_null() &&
-           !script_.is_null());
+  virtual Handle<JSFunction> closure() const {
+    return Handle<JSFunction>::null();
   }

-  // We can only get a JSFunction if we actually have one.
-  Handle<JSFunction> closure() { return closure_; }
-
-  // We can get a SharedFunctionInfo from a JSFunction or if we actually
-  // have one.
-  Handle<SharedFunctionInfo> shared_info() {
-    if (!closure().is_null()) {
-      return Handle<SharedFunctionInfo>(closure()->shared());
-    } else {
-      return shared_info_;
-    }
-  }
-
-  // We can always get a script.  Either we have one or we can get a shared
-  // function info.
-  Handle<Script> script() {
-    if (!script_.is_null()) {
-      return script_;
-    } else {
-      ASSERT(shared_info()->script()->IsScript());
-      return Handle<Script>(Script::cast(shared_info()->script()));
-    }
-  }
+  virtual bool is_eval() const { return false; }
+
+  virtual int loop_nesting() const { return 0; }
+
+  virtual bool has_global_object() const { return false; }
+  virtual GlobalObject* global_object() const { return NULL; }

   // There should always be a function literal, but it may be set after
   // construction (for lazy compilation).
   FunctionLiteral* function() { return function_; }
   void set_function(FunctionLiteral* literal) { function_ = literal; }

-  // Simple accessors.
-  bool is_eval() { return is_eval_; }
-  int loop_nesting() { return loop_nesting_; }
-
-  bool has_global_object() {
- return !closure().is_null() && (closure()->context()->global() != NULL);
+  // Derived accessors.
+  Scope* scope() { return function()->scope(); }
+
+ protected:
+  CompilationInfo() : function_(NULL) {}
+
+ private:
+  FunctionLiteral* function_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
+};
+
+
+class EagerCompilationInfo: public CompilationInfo {
+ public:
+  EagerCompilationInfo(Handle<Script> script, bool is_eval)
+      : script_(script), is_eval_(is_eval) {
+    ASSERT(!script.is_null());
   }

-  GlobalObject* global_object() {
-    return has_global_object() ? closure()->context()->global() : NULL;
+  // Overridden functions from the base class.
+  virtual Handle<SharedFunctionInfo> shared_info() const {
+    return Handle<SharedFunctionInfo>::null();
   }

-  // Derived accessors.
-  Scope* scope() { return function()->scope(); }
+  virtual Handle<Script> script() const { return script_; }
+
+  virtual bool is_eval() const { return is_eval_; }

  private:
-  Handle<JSFunction> closure_;
-  Handle<SharedFunctionInfo> shared_info_;
   Handle<Script> script_;
-
-  FunctionLiteral* function_;
-
-  bool is_eval_;
-  int loop_nesting_;
-
-  DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
+  bool is_eval_;
+};
+
+
+class LazySharedCompilationInfo: public CompilationInfo {
+ public:
+ explicit LazySharedCompilationInfo(Handle<SharedFunctionInfo> shared_info)
+      : shared_info_(shared_info) {
+    ASSERT(!shared_info.is_null());
+  }
+
+  // Overridden functions from the base class.
+  virtual Handle<SharedFunctionInfo> shared_info() const {
+    return shared_info_;
+  }
+
+ private:
+  Handle<SharedFunctionInfo> shared_info_;
+};
+
+
+class LazyFunctionCompilationInfo: public CompilationInfo {
+ public:
+  LazyFunctionCompilationInfo(Handle<JSFunction> closure,
+                              int loop_nesting)
+      : closure_(closure), loop_nesting_(loop_nesting) {
+    ASSERT(!closure.is_null());
+  }
+
+  // Overridden functions from the base class.
+  virtual Handle<SharedFunctionInfo> shared_info() const {
+    return Handle<SharedFunctionInfo>(closure_->shared());
+  }
+
+  virtual int loop_nesting() const { return loop_nesting_; }
+
+  virtual bool has_global_object() const {
+    return closure_->context()->global() != NULL;
+  }
+
+  virtual GlobalObject* global_object() const {
+    return closure_->context()->global();
+  }
+
+ private:
+  Handle<JSFunction> closure_;
+  int loop_nesting_;
 };


=======================================
--- /branches/bleeding_edge/src/handles.cc      Wed Sep 29 10:38:37 2010
+++ /branches/bleeding_edge/src/handles.cc      Thu Sep 30 01:48:37 2010
@@ -779,7 +779,7 @@

 bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
                        ClearExceptionFlag flag) {
-  CompilationInfo info(shared);
+  LazySharedCompilationInfo info(shared);
   return CompileLazyHelper(&info, flag);
 }

@@ -791,7 +791,7 @@
     function->shared()->set_code_age(0);
     return true;
   } else {
-    CompilationInfo info(function, 0);
+    LazyFunctionCompilationInfo info(function, 0);
     bool result = CompileLazyHelper(&info, flag);
     PROFILE(FunctionCreateEvent(*function));
     return result;
@@ -806,7 +806,7 @@
     function->shared()->set_code_age(0);
     return true;
   } else {
-    CompilationInfo info(function, 1);
+    LazyFunctionCompilationInfo info(function, 1);
     bool result = CompileLazyHelper(&info, flag);
     PROFILE(FunctionCreateEvent(*function));
     return result;
=======================================
--- /branches/bleeding_edge/src/liveedit.cc     Fri Sep 24 00:53:59 2010
+++ /branches/bleeding_edge/src/liveedit.cc     Thu Sep 30 01:48:37 2010
@@ -408,6 +408,7 @@

   // Build AST.
   ScriptDataImpl* pre_data = NULL;
+  EagerCompilationInfo info(script, is_eval);
   FunctionLiteral* lit = MakeAST(is_global, script, extension, pre_data);

   // Check for parse errors.
@@ -415,10 +416,9 @@
     ASSERT(Top::has_pending_exception());
     return;
   }
+  info.set_function(lit);

   // Compile the code.
-  CompilationInfo info(lit, script, is_eval);
-
   LiveEditFunctionTracker tracker(lit);
   Handle<Code> code = MakeCodeForLiveEdit(&info);

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

Reply via email to