Commit 89c762ed authored by iposva@chromium.org's avatar iposva@chromium.org

Simplify CodeGenerator hierarchy by not using a base class.

There is nothing virtual about a CodeGenerator since we
either generate code for one platform or for the other.

Review URL: http://codereview.chromium.org/6334

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@480 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 015af31d
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -27,8 +27,11 @@
#include "v8.h"
#include "bootstrapper.h"
#include "codegen-inl.h"
#include "debug.h"
#include "prettyprinter.h"
#include "scopeinfo.h"
#include "runtime.h"
#include "stub-cache.h"
......@@ -68,6 +71,97 @@ void CodeGenerator::ProcessDeferred() {
}
// Generate the code. Takes a function literal, generates code for it, assemble
// all the pieces into a Code object. This function is only to be called by
// the compiler.cc code.
Handle<Code> CodeGenerator::MakeCode(FunctionLiteral* flit,
Handle<Script> script,
bool is_eval) {
#ifdef ENABLE_DISASSEMBLER
bool print_code = FLAG_print_code && !Bootstrapper::IsActive();
#endif
#ifdef DEBUG
bool print_source = false;
bool print_ast = false;
const char* ftype;
if (Bootstrapper::IsActive()) {
print_source = FLAG_print_builtin_source;
print_ast = FLAG_print_builtin_ast;
print_code = FLAG_print_builtin_code;
ftype = "builtin";
} else {
print_source = FLAG_print_source;
print_ast = FLAG_print_ast;
ftype = "user-defined";
}
if (FLAG_trace_codegen || print_source || print_ast) {
PrintF("*** Generate code for %s function: ", ftype);
flit->name()->ShortPrint();
PrintF(" ***\n");
}
if (print_source) {
PrintF("--- Source from AST ---\n%s\n", PrettyPrinter().PrintProgram(flit));
}
if (print_ast) {
PrintF("--- AST ---\n%s\n", AstPrinter().PrintProgram(flit));
}
#endif // DEBUG
// Generate code.
const int initial_buffer_size = 4 * KB;
CodeGenerator cgen(initial_buffer_size, script, is_eval);
cgen.GenCode(flit);
if (cgen.HasStackOverflow()) {
ASSERT(!Top::has_pending_exception());
return Handle<Code>::null();
}
// Process any deferred code.
cgen.ProcessDeferred();
// Allocate and install the code.
CodeDesc desc;
cgen.masm()->GetCode(&desc);
ScopeInfo<> sinfo(flit->scope());
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
Handle<Code> code = Factory::NewCode(desc, &sinfo, flags);
// Add unresolved entries in the code to the fixup list.
Bootstrapper::AddFixup(*code, cgen.masm());
#ifdef ENABLE_DISASSEMBLER
if (print_code) {
// Print the source code if available.
if (!script->IsUndefined() && !script->source()->IsUndefined()) {
PrintF("--- Raw source ---\n");
StringInputBuffer stream(String::cast(script->source()));
stream.Seek(flit->start_position());
// flit->end_position() points to the last character in the stream. We
// need to compensate by adding one to calculate the length.
int source_len = flit->end_position() - flit->start_position() + 1;
for (int i = 0; i < source_len; i++) {
if (stream.has_more()) PrintF("%c", stream.GetNext());
}
PrintF("\n\n");
}
PrintF("--- Code ---\n");
code->Disassemble();
}
#endif // ENABLE_DISASSEMBLER
if (!code.is_null()) {
Counters::total_compiled_code_size.Increment(code->instruction_size());
}
return code;
}
// Sets the function info on a function.
// The start_position points to the first '(' character after the function name
// in the full script source. When counting characters in the script source the
......
......@@ -26,12 +26,43 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_CODEGEN_H_
#define V8_CODEGEN_H_
#include "ast.h"
#include "code-stubs.h"
#include "runtime.h"
#define V8_CODEGEN_H_
// Include the declaration of the architecture defined class CodeGenerator.
// The contract to the shared code is that the the CodeGenerator is a subclass
// of Visitor and that the following methods are available publicly:
// CodeGenerator::MakeCode
// CodeGenerator::SetFunctionInfo
// CodeGenerator::AddDeferred
// CodeGenerator::masm
//
// These methods are either used privately by the shared code or implemented as
// shared code:
// CodeGenerator::CodeGenerator
// CodeGenerator::~CodeGenerator
// CodeGenerator::ProcessDeferred
// CodeGenerator::GenCode
// CodeGenerator::BuildBoilerplate
// CodeGenerator::ComputeCallInitialize
// CodeGenerator::ProcessDeclarations
// CodeGenerator::DeclareGlobals
// CodeGenerator::CheckForInlineRuntimeCall
// CodeGenerator::GenerateFastCaseSwitchStatement
// CodeGenerator::GenerateFastCaseSwitchCases
// CodeGenerator::TryGenerateFastCaseSwitchStatement
// CodeGenerator::GenerateFastCaseSwitchJumpTable
// CodeGenerator::FastCaseSwitchMinCaseCount
// CodeGenerator::FastCaseSwitchMaxOverheadFactor
#if defined(ARM)
#include "codegen-arm.h"
#else
#include "codegen-ia32.h"
#endif
namespace v8 { namespace internal {
......@@ -43,10 +74,6 @@ namespace v8 { namespace internal {
// and we can only run the tests with --nolazy.
// Forward declaration.
class CodeGenerator;
// Deferred code objects are small pieces of code that are compiled
// out of line. They are used to defer the compilation of uncommon
// paths thereby avoiding expensive jumps around uncommon code parts.
......@@ -93,124 +120,6 @@ class DeferredCode: public ZoneObject {
};
// A superclass for code generators. The implementations of methods
// declared in this class are partially in codegen.c and partially in
// codegen_<arch>.c.
class CodeGenerator: public Visitor {
public:
CodeGenerator(bool is_eval,
Handle<Script> script)
: is_eval_(is_eval),
script_(script),
deferred_(8) { }
// The code generator: Takes a function literal, generates code for it,
// and assembles it all into a Code* object. This function should only
// be called by compiler.cc.
static Handle<Code> MakeCode(FunctionLiteral* fun,
Handle<Script> script,
bool is_eval);
static void SetFunctionInfo(Handle<JSFunction> fun,
int length,
int function_token_position,
int start_position,
int end_position,
bool is_expression,
bool is_toplevel,
Handle<Script> script);
virtual MacroAssembler* masm() = 0;
virtual Scope* scope() const = 0;
void AddDeferred(DeferredCode* code) { deferred_.Add(code); }
void ProcessDeferred();
// Accessors for is_eval.
bool is_eval() { return is_eval_; }
// Abstract node visitors.
#define DEF_VISIT(type) \
virtual void Visit##type(type* node) = 0;
NODE_LIST(DEF_VISIT)
#undef DEF_VISIT
protected:
bool CheckForInlineRuntimeCall(CallRuntime* node);
Handle<JSFunction> BuildBoilerplate(FunctionLiteral* node);
void ProcessDeclarations(ZoneList<Declaration*>* declarations);
Handle<Code> ComputeCallInitialize(int argc);
// Declare global variables and functions in the given array of
// name/value pairs.
virtual void DeclareGlobals(Handle<FixedArray> pairs) = 0;
// Support for type checks.
virtual void GenerateIsSmi(ZoneList<Expression*>* args) = 0;
virtual void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) = 0;
virtual void GenerateIsArray(ZoneList<Expression*>* args) = 0;
// Support for arguments.length and arguments[?].
virtual void GenerateArgumentsLength(ZoneList<Expression*>* args) = 0;
virtual void GenerateArgumentsAccess(ZoneList<Expression*>* args) = 0;
// Support for accessing the value field of an object (used by Date).
virtual void GenerateValueOf(ZoneList<Expression*>* args) = 0;
virtual void GenerateSetValueOf(ZoneList<Expression*>* args) = 0;
// Fast support for charCodeAt(n).
virtual void GenerateFastCharCodeAt(ZoneList<Expression*>* args) = 0;
// Fast support for object equality testing.
virtual void GenerateObjectEquals(ZoneList<Expression*>* args) = 0;
// Multiple methods for fast case switch statement support.
// The limit of the range of a fast-case switch, as a factor of the number
// of cases of the switch. Each platform should return a value that
// is optimal compared to the default code generated for a switch statement
// on that platform.
virtual int FastCaseSwitchMaxOverheadFactor() = 0;
// The minimal number of cases in a switch before the fast-case switch
// optimization is enabled. Each platform should return a value that
// is optimal compared to the default code generated for a switch statement
// on that platform.
virtual int FastCaseSwitchMinCaseCount() = 0;
// Allocate a jump table and create code to jump through it.
// Should call GenerateFastCaseSwitchCases to generate the code for
// all the cases at the appropriate point.
virtual void GenerateFastCaseSwitchJumpTable(
SwitchStatement* node, int min_index, int range, Label *fail_label,
SmartPointer<Label*> &case_targets, SmartPointer<Label>& case_labels) = 0;
// Generate the code for cases for the fast case switch.
// Called by GenerateFastCaseSwitchJumpTable.
virtual void GenerateFastCaseSwitchCases(
SwitchStatement* node, SmartPointer<Label> &case_labels);
// Fast support for constant-Smi switches.
virtual void GenerateFastCaseSwitchStatement(
SwitchStatement *node, int min_index, int range, int default_index);
// Fast support for constant-Smi switches. Tests whether switch statement
// permits optimization and calls GenerateFastCaseSwitch if it does.
// Returns true if the fast-case switch was generated, and false if not.
virtual bool TryGenerateFastCaseSwitchStatement(SwitchStatement *node);
private:
bool is_eval_; // Tells whether code is generated for eval.
Handle<Script> script_;
List<DeferredCode*> deferred_;
};
// RuntimeStub models code stubs calling entry points in the Runtime class.
class RuntimeStub : public CodeStub {
public:
......
......@@ -247,6 +247,8 @@
8900116B0E71CA2300F91F35 /* libraries.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = libraries.cc; sourceTree = "<group>"; };
89495E460E79FC23001F68C3 /* compilation-cache.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "compilation-cache.cc"; sourceTree = "<group>"; };
89495E470E79FC23001F68C3 /* compilation-cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "compilation-cache.h"; sourceTree = "<group>"; };
8964482B0E9C00F700E7C516 /* codegen-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "codegen-ia32.h"; sourceTree = "<group>"; };
896448BC0E9D530500E7C516 /* codegen-arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "codegen-arm.h"; sourceTree = "<group>"; };
8970F2F00E719FB2006AE7B5 /* libv8.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libv8.a; sourceTree = BUILT_PRODUCTS_DIR; };
897F767A0E71B4CC007ACF34 /* v8_shell */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = v8_shell; sourceTree = BUILT_PRODUCTS_DIR; };
897FF0D40E719A8500D62E90 /* v8-debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "v8-debug.h"; sourceTree = "<group>"; };
......@@ -456,8 +458,8 @@
897FF1B50E719C0900D62E90 /* shell.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shell.cc; sourceTree = "<group>"; };
897FF1B60E719C2300D62E90 /* js2c.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = js2c.py; sourceTree = "<group>"; };
897FF1B70E719C2E00D62E90 /* macros.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = macros.py; path = ../src/macros.py; sourceTree = "<group>"; };
89B12E8D0E7FF2A40080BA62 /* presubmit.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = presubmit.py; sourceTree = "<group>"; };
897FF1BF0E719CB600D62E90 /* libjscre.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjscre.a; sourceTree = BUILT_PRODUCTS_DIR; };
89B12E8D0E7FF2A40080BA62 /* presubmit.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = presubmit.py; sourceTree = "<group>"; };
89F23C870E78D5B2006B2466 /* libv8-arm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libv8-arm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
89F23C950E78D5B6006B2466 /* v8_shell-arm */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "v8_shell-arm"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
......@@ -579,7 +581,9 @@
897FF1120E719B8F00D62E90 /* code-stubs.h */,
897FF1130E719B8F00D62E90 /* code.h */,
897FF1140E719B8F00D62E90 /* codegen-arm.cc */,
896448BC0E9D530500E7C516 /* codegen-arm.h */,
897FF1150E719B8F00D62E90 /* codegen-ia32.cc */,
8964482B0E9C00F700E7C516 /* codegen-ia32.h */,
897FF1160E719B8F00D62E90 /* codegen-inl.h */,
897FF1170E719B8F00D62E90 /* codegen.cc */,
897FF1180E719B8F00D62E90 /* codegen.h */,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment