Commit 22e4847f authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

ARM: Update the full compiler to handle all code

The full compiler is now complete on ARM as well. The syntax checker is still used to determine whether to use it for top level code or not during normal execution. When debugging is enabled all code will be compiled with the full compiler.

This change removes the temporary flag --force-full-compiler and now the flag --always-full-compiler enables the full compiler for all code on all platforms.

This also fixes building on Intel platform without debugger support (ENABLE_DEBUGGER_SUPPORT not defined) and adds full check for the full compiler for lazily compiled code.
Review URL: http://codereview.chromium.org/2163006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4716 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 675e711f
......@@ -2309,8 +2309,6 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
__ cmp(r0, r1); // compare to the array length
node->break_target()->Branch(hs);
__ ldr(r0, frame_->ElementAt(0));
// Get the i'th entry of the array.
__ ldr(r2, frame_->ElementAt(2));
__ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
......@@ -4212,9 +4210,8 @@ void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
__ ldr(map_reg, FieldMemOperand(r1, HeapObject::kMapOffset));
// Undetectable objects behave like undefined when tested with typeof.
__ ldrb(r1, FieldMemOperand(map_reg, Map::kBitFieldOffset));
__ and_(r1, r1, Operand(1 << Map::kIsUndetectable));
__ cmp(r1, Operand(1 << Map::kIsUndetectable));
false_target()->Branch(eq);
__ tst(r1, Operand(1 << Map::kIsUndetectable));
false_target()->Branch(ne);
__ ldrb(r1, FieldMemOperand(map_reg, Map::kInstanceTypeOffset));
__ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
......
This diff is collapsed.
......@@ -44,6 +44,18 @@
namespace v8 {
namespace internal {
// For normal operation the syntax checker is used to determine whether to
// use the full compiler for top level code or not. However if the flag
// --always-full-compiler is specified or debugging is active the full
// compiler will be used for all code.
static bool AlwaysFullCompiler() {
#ifdef ENABLE_DEBUGGER_SUPPORT
return FLAG_always_full_compiler || Debugger::IsDebuggerActive();
#else
return FLAG_always_full_compiler;
#endif
}
static Handle<Code> MakeCode(Handle<Context> context, CompilationInfo* info) {
FunctionLiteral* function = info->function();
......@@ -120,21 +132,9 @@ static Handle<Code> MakeCode(Handle<Context> context, CompilationInfo* info) {
? info->scope()->is_global_scope()
: (shared->is_toplevel() || shared->try_full_codegen());
bool force_full_compiler = false;
#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X64)
// On ia32 the full compiler can compile all code whereas the other platforms
// the constructs supported is checked by the associated syntax checker. When
// --always-full-compiler is used on ia32 the syntax checker is still in
// effect, but there is a special flag --force-full-compiler to ignore the
// syntax checker completely and use the full compiler for all code. Also
// when debugging on ia32 the full compiler will be used for all code.
force_full_compiler =
Debugger::IsDebuggerActive() || FLAG_force_full_compiler;
#endif
if (force_full_compiler) {
if (AlwaysFullCompiler()) {
return FullCodeGenerator::MakeCode(info);
} else if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
} else if (FLAG_full_compiler && is_run_once) {
FullCodeGenSyntaxChecker checker;
checker.Check(function);
if (checker.has_supported_syntax()) {
......@@ -521,7 +521,11 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
bool is_run_once = literal->try_full_codegen();
bool is_compiled = false;
if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
if (AlwaysFullCompiler()) {
code = FullCodeGenerator::MakeCode(&info);
is_compiled = true;
} else if (FLAG_full_compiler && is_run_once) {
FullCodeGenSyntaxChecker checker;
checker.Check(literal);
if (checker.has_supported_syntax()) {
......
......@@ -149,10 +149,6 @@ DEFINE_bool(full_compiler, true, "enable dedicated backend for run-once code")
DEFINE_bool(fast_compiler, false, "enable speculative optimizing backend")
DEFINE_bool(always_full_compiler, false,
"try to use the dedicated run-once backend for all code")
#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X64)
DEFINE_bool(force_full_compiler, false,
"force use of the dedicated run-once backend for all code")
#endif
DEFINE_bool(always_fast_compiler, false,
"try to use the speculative optimizing backend for all code")
DEFINE_bool(trace_bailout, false,
......
......@@ -2220,9 +2220,7 @@ void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
// Check that the object is a JS object but take special care of JS
// functions to make sure they have 'Function' as their class.
__ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
__ movzx_b(ebx, FieldOperand(eax, Map::kInstanceTypeOffset));
__ cmp(ebx, FIRST_JS_OBJECT_TYPE);
__ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, eax); // Map is now in eax.
__ j(below, &null);
// As long as JS_FUNCTION_TYPE is the last instance type and it is
......
......@@ -74,6 +74,8 @@ class JumpTarget : public ZoneObject { // Shadows are dynamically allocated.
inline CodeGenerator* cgen();
Label* entry_label() { return &entry_label_; }
const VirtualFrame* entry_frame() const {
return entry_frame_set_ ? &entry_frame_ : NULL;
}
......
......@@ -2215,7 +2215,7 @@ void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
// Check that the object is a JS object but take special care of JS
// functions to make sure they have 'Function' as their class.
__ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax);
__ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax); // Map is now in rax.
__ j(below, &null);
// As long as JS_FUNCTION_TYPE is the last instance type and it is
......
......@@ -273,12 +273,10 @@ static void CreateTraceCallerFunction(const char* func_name,
// StackTracer uses Top::c_entry_fp as a starting point for stack
// walking.
TEST(CFromJSStackTrace) {
#if defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64)
// TODO(711) The hack of replacing the inline runtime function
// RandomHeapNumber with GetFrameNumber does not work with the way the full
// compiler generates inline runtime calls.
i::FLAG_force_full_compiler = false;
#endif
i::FLAG_always_full_compiler = false;
TickSample sample;
InitTraceEnv(&sample);
......@@ -315,12 +313,10 @@ TEST(CFromJSStackTrace) {
// Top::c_entry_fp value. In this case, StackTracer uses passed frame
// pointer value as a starting point for stack walking.
TEST(PureJSStackTrace) {
#if defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64)
// TODO(711) The hack of replacing the inline runtime function
// RandomHeapNumber with GetFrameNumber does not work with the way the full
// compiler generates inline runtime calls.
i::FLAG_force_full_compiler = false;
#endif
i::FLAG_always_full_compiler = false;
TickSample sample;
InitTraceEnv(&sample);
......
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