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
This commit is contained in:
parent
675e711f1c
commit
22e4847fde
@ -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));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user