Introduce subclasses of class CompilationInfo.
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 30 Sep 2010 08:48:37 +0000 (08:48 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 30 Sep 2010 08:48:37 +0000 (08:48 +0000)
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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5560 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/compiler.cc
src/compiler.h
src/handles.cc
src/liveedit.cc

index 825198e..ba8aca0 100755 (executable)
@@ -146,9 +146,10 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(bool is_global,
   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 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(bool is_global,
   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 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(bool is_global,
   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 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
     // 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();
index 10d93dc..ae0d6de 100644 (file)
@@ -41,94 +41,109 @@ namespace internal {
 // 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());
-  }
+  virtual ~CompilationInfo() {}
+
+  // Dispatched behavior.
+  virtual Handle<SharedFunctionInfo> shared_info() const = 0;
 
-  // 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 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_; }
+  virtual bool is_eval() const { return false; }
 
-  // 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_;
-    }
-  }
+  virtual int loop_nesting() const { return 0; }
 
-  // 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 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_; }
+  // Derived accessors.
+  Scope* scope() { return function()->scope(); }
+
+ protected:
+  CompilationInfo() : function_(NULL) {}
+
+ private:
+  FunctionLiteral* function_;
 
-  bool has_global_object() {
-    return !closure().is_null() && (closure()->context()->global() != NULL);
+  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_;
+  bool is_eval_;
+};
 
-  FunctionLiteral* function_;
 
-  bool is_eval_;
-  int loop_nesting_;
+class LazySharedCompilationInfo: public CompilationInfo {
+ public:
+  explicit LazySharedCompilationInfo(Handle<SharedFunctionInfo> shared_info)
+      : shared_info_(shared_info) {
+    ASSERT(!shared_info.is_null());
+  }
 
-  DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
+  // 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_;
 };
 
 
index d8a25b1..0207492 100644 (file)
@@ -779,7 +779,7 @@ static bool CompileLazyHelper(CompilationInfo* info,
 
 bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
                        ClearExceptionFlag flag) {
-  CompilationInfo info(shared);
+  LazySharedCompilationInfo info(shared);
   return CompileLazyHelper(&info, flag);
 }
 
@@ -791,7 +791,7 @@ bool CompileLazy(Handle<JSFunction> function,
     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 @@ bool CompileLazyInLoop(Handle<JSFunction> function,
     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;
index c07e83f..2fae3af 100644 (file)
@@ -408,6 +408,7 @@ static void CompileScriptForTracker(Handle<Script> script) {
 
   // 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 @@ static void CompileScriptForTracker(Handle<Script> script) {
     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);