Generalized the EvalCache into a CompilationCache and enabled it for scripts too.  The current strategy is to retire all entries whenever a mark-sweep collection is started.

Fixed bug where switch statements containing only a default case would lead to an unbalanced stack (issue 69).

Fixed bug that made access to the function in a named function expression impossible in certain situations (issue 24).

Fixed even more build issues.

Optimized calling conventions on ARM.  The conventions on ARM and IA-32 now match.

Removed static initializers for flags and counters.

Improved inline caching behavior for uncommon cases where lazily loading Date and RegExp code could force certain code paths go megamorphic.

Removed arguments adaption for builtins written in C++.  This makes Array.prototype.push and Array.prototype.pop slightly faster.


git-svn-id: http://v8.googlecode.com/svn/trunk@329 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 33cfd0b..cbd02ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2008-09-17: Version 0.3.2
+
+        Generalized the EvalCache into a CompilationCache and enabled it
+        for scripts too.  The current strategy is to retire all entries
+        whenever a mark-sweep collection is started.
+
+        Fixed bug where switch statements containing only a default case
+        would lead to an unbalanced stack (issue 69).
+
+        Fixed bug that made access to the function in a named function
+        expression impossible in certain situations (issue 24).
+
+        Fixed even more build issues.
+
+        Optimized calling conventions on ARM.  The conventions on ARM and
+        IA-32 now match.
+
+        Removed static initializers for flags and counters.
+
+        Improved inline caching behavior for uncommon cases where lazily
+        loading Date and RegExp code could force certain code paths go
+        megamorphic.
+
+        Removed arguments adaption for builtins written in C++.  This
+        makes Array.prototype.push and Array.prototype.pop slightly
+        faster.
+
+
 2008-09-11: Version 0.3.1
 
         Fixed a number of build issues.
diff --git a/SConstruct b/SConstruct
index a2bed56..b6fc04f 100644
--- a/SConstruct
+++ b/SConstruct
@@ -63,12 +63,9 @@
   'msvc': {
     'all': {
       'DIALECTFLAGS': ['/nologo'],
-      'WARNINGFLAGS': ['/W3', '/WX', '/wd4355', '/wd4800'],
       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
       'CXXFLAGS':     ['$CCFLAGS', '/GR-', '/Gy'],
-      'CPPDEFINES':   ['WIN32', '_CRT_SECURE_NO_DEPRECATE',
-          '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T',
-          'PCRE_STATIC'],
+      'CPPDEFINES':   ['WIN32', '_USE_32BIT_TIME_T', 'PCRE_STATIC'],
       'LINKFLAGS':    ['/NOLOGO', '/MACHINE:X86', '/INCREMENTAL:NO',
           '/NXCOMPAT', '/IGNORE:4221'],
       'ARFLAGS':      ['/NOLOGO'],
@@ -456,6 +453,7 @@
   )
   
   # Link the object files into a library.
+  env.Replace(**context.flags['v8'])
   context.ApplyEnvOverrides(env)
   if context.options['library'] == 'static':
     library = env.StaticLibrary(library_name, object_files)
diff --git a/src/SConscript b/src/SConscript
index cc39e22..725f935 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -37,9 +37,9 @@
   'all': [
     'accessors.cc', 'allocation.cc', 'api.cc', 'assembler.cc', 'ast.cc',
     'bootstrapper.cc', 'builtins.cc', 'checks.cc', 'code-stubs.cc',
-    'codegen.cc', 'compiler.cc', 'contexts.cc', 'conversions.cc',
-    'counters.cc', 'dateparser.cc', 'debug.cc', 'disassembler.cc',
-    'execution.cc', 'factory.cc', 'flags.cc', 'frames.cc',
+    'codegen.cc', 'compilation-cache.cc', 'compiler.cc', 'contexts.cc',
+    'conversions.cc', 'counters.cc', 'dateparser.cc', 'debug.cc',
+    'disassembler.cc', 'execution.cc', 'factory.cc', 'flags.cc', 'frames.cc',
     'global-handles.cc', 'handles.cc', 'hashmap.cc', 'heap.cc', 'ic.cc',
     'jsregexp.cc', 'log.cc', 'mark-compact.cc', 'messages.cc', 'objects.cc',
     'parser.cc', 'property.cc', 'rewriter.cc', 'runtime.cc', 'scanner.cc',
@@ -125,7 +125,7 @@
 
   source_objs = context.ConfigureObject(env, source_files)
   non_snapshot_files = [jscre_obj, dtoa_obj, source_objs]
-  
+
   # Create snapshot if necessary.
   empty_snapshot_obj = context.ConfigureObject(env, 'snapshot-empty.cc')
   if context.use_snapshot:
diff --git a/src/api.cc b/src/api.cc
index 8cf4b62..79ef605 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2216,7 +2216,7 @@
 
 
 const char* v8::V8::GetVersion() {
-  return "0.3.1";
+  return "0.3.2";
 }
 
 
diff --git a/src/assembler-arm.cc b/src/assembler-arm.cc
index e057fe0..12d110b 100644
--- a/src/assembler-arm.cc
+++ b/src/assembler-arm.cc
@@ -41,10 +41,6 @@
 
 namespace v8 { namespace internal {
 
-DEFINE_bool(debug_code, false,
-            "generate extra code (comments, assertions) for debugging");
-
-
 // -----------------------------------------------------------------------------
 // Implementation of Register and CRegister
 
@@ -272,11 +268,6 @@
 };
 
 
-DEFINE_bool(push_pop_elimination, true,
-            "eliminate redundant push/pops in assembly code");
-DEFINE_bool(print_push_pop_elimination, false,
-            "print elimination of redundant push/pops in assembly code");
-
 // add(sp, sp, 4) instruction (aka Pop())
 static const Instr kPopInstruction =
     al | 4 * B21 | 4 | LeaveCC | I | sp.code() * B16 | sp.code() * B12;
@@ -469,10 +460,6 @@
 }
 
 
-DEFINE_bool(eliminate_jumps, true, "eliminate jumps to jumps in assembly code");
-DEFINE_bool(print_jump_elimination, false,
-            "print elimination of jumps to jumps in assembly code");
-
 void Assembler::bind_to(Label* L, int pos) {
   ASSERT(0 <= pos && pos <= pc_offset());  // must have a valid binding position
   while (L->is_linked()) {
diff --git a/src/assembler-arm.h b/src/assembler-arm.h
index 8591362..b9fa81d 100644
--- a/src/assembler-arm.h
+++ b/src/assembler-arm.h
@@ -459,6 +459,10 @@
 
   void sub(Register dst, Register src1, const Operand& src2,
            SBit s = LeaveCC, Condition cond = al);
+  void sub(Register dst, Register src1, Register src2,
+           SBit s = LeaveCC, Condition cond = al) {
+    sub(dst, src1, Operand(src2), s, cond);
+  }
 
   void rsb(Register dst, Register src1, const Operand& src2,
            SBit s = LeaveCC, Condition cond = al);
@@ -476,18 +480,31 @@
            SBit s = LeaveCC, Condition cond = al);
 
   void tst(Register src1, const Operand& src2, Condition cond = al);
+  void tst(Register src1, Register src2, Condition cond = al) {
+    tst(src1, Operand(src2), cond);
+  }
 
   void teq(Register src1, const Operand& src2, Condition cond = al);
 
   void cmp(Register src1, const Operand& src2, Condition cond = al);
+  void cmp(Register src1, Register src2, Condition cond = al) {
+    cmp(src1, Operand(src2), cond);
+  }
 
   void cmn(Register src1, const Operand& src2, Condition cond = al);
 
   void orr(Register dst, Register src1, const Operand& src2,
            SBit s = LeaveCC, Condition cond = al);
+  void orr(Register dst, Register src1, Register src2,
+           SBit s = LeaveCC, Condition cond = al) {
+    orr(dst, src1, Operand(src2), s, cond);
+  }
 
   void mov(Register dst, const Operand& src,
            SBit s = LeaveCC, Condition cond = al);
+  void mov(Register dst, Register src, SBit s = LeaveCC, Condition cond = al) {
+    mov(dst, Operand(src), s, cond);
+  }
 
   void bic(Register dst, Register src1, const Operand& src2,
            SBit s = LeaveCC, Condition cond = al);
diff --git a/src/assembler-ia32.cc b/src/assembler-ia32.cc
index 483ae0e..3f2b2c9 100644
--- a/src/assembler-ia32.cc
+++ b/src/assembler-ia32.cc
@@ -42,10 +42,6 @@
 
 namespace v8 { namespace internal {
 
-DEFINE_bool(debug_code, false,
-            "generate extra code (comments, assertions) for debugging");
-DEFINE_bool(emit_branch_hints, false, "emit branch hints");
-
 // -----------------------------------------------------------------------------
 // Implementation of Register
 
@@ -412,11 +408,6 @@
 }
 
 
-DEFINE_bool(push_pop_elimination, true,
-            "eliminate redundant push/pops in assembly code");
-DEFINE_bool(print_push_pop_elimination, false,
-            "print elimination of redundant push/pops in assembly code");
-
 void Assembler::push(Register src) {
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
@@ -1180,10 +1171,6 @@
 }
 
 
-DEFINE_bool(eliminate_jumps, true, "eliminate jumps to jumps in assembly code");
-DEFINE_bool(print_jump_elimination, false,
-            "print elimination of jumps to jumps in assembly code");
-
 void Assembler::bind_to(Label* L, int pos) {
   EnsureSpace ensure_space(this);
   last_pc_ = NULL;
diff --git a/src/ast.h b/src/ast.h
index ab7bc8d..8bece05 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -140,6 +140,9 @@
 };
 
 
+class Reference;
+enum InitState { CONST_INIT, NOT_CONST_INIT };
+
 class Expression: public Node {
  public:
   virtual Expression* AsExpression()  { return this; }
@@ -150,6 +153,18 @@
   // statement. This is used to transform postfix increments to
   // (faster) prefix increments.
   virtual void MarkAsStatement() { /* do nothing */ }
+
+  // Generate code to store into an expression evaluated as the left-hand
+  // side of an assignment.  The code will expect the stored value on top of
+  // the expression stack, and a reference containing the expression
+  // immediately below that.  This function is overridden for expression
+  // types that can be stored into.
+  virtual void GenerateStoreCode(MacroAssembler* masm,
+                                 Scope* scope,
+                                 Reference* ref,
+                                 InitState init_state) {
+    UNREACHABLE();
+  }
 };
 
 
@@ -753,6 +768,14 @@
   // Bind this proxy to the variable var.
   void BindTo(Variable* var);
 
+  // Generate code to store into an expression evaluated as the left-hand
+  // side of an assignment.  The code will expect the stored value on top of
+  // the expression stack, and a reference containing the expression
+  // immediately below that.
+  virtual void GenerateStoreCode(MacroAssembler* masm,
+                                 Scope* scope,
+                                 Reference* ref,
+                                 InitState init_state);
  protected:
   Handle<String> name_;
   Variable* var_;  // resolved variable, or NULL
@@ -828,6 +851,14 @@
   Type type() const  { return type_; }
   int index() const  { return index_; }
 
+  // Generate code to store into an expression evaluated as the left-hand
+  // side of an assignment.  The code will expect the stored value on top of
+  // the expression stack, and a reference containing the expression
+  // immediately below that.
+  virtual void GenerateStoreCode(MacroAssembler* masm,
+                                 Scope* scope,
+                                 Reference* ref,
+                                 InitState init_state);
  private:
   Variable* var_;
   Type type_;
@@ -855,6 +886,14 @@
   // during preparsing.
   static Property* this_property() { return &this_property_; }
 
+  // Generate code to store into an expression evaluated as the left-hand
+  // side of an assignment.  The code will expect the stored value on top of
+  // the expression stack, and a reference containing the expression
+  // immediately below that.
+  virtual void GenerateStoreCode(MacroAssembler* masm,
+                                 Scope* scope,
+                                 Reference* ref,
+                                 InitState init_state);
  private:
   Expression* obj_;
   Expression* key_;
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 1006108..71c1076 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -39,11 +39,6 @@
 
 namespace v8 { namespace internal {
 
-DEFINE_string(expose_natives_as, NULL, "expose natives in global object");
-DEFINE_string(expose_debug_as, NULL, "expose debug in global object");
-DEFINE_string(natives_file, NULL, "alternative natives file");  // for debugging
-DEFINE_bool(expose_gc, false, "expose gc extension");  // for debugging
-
 // A SourceCodeCache uses a FixedArray to store pairs of
 // (AsciiString*, JSFunction*), mapping names of native code files
 // (runtime.js, etc.) to precompiled functions. Instead of mapping
@@ -296,8 +291,7 @@
 
   void AddSpecialFunction(Handle<JSObject> prototype,
                           const char* name,
-                          Handle<Code> code,
-                          int parameter_count);
+                          Handle<Code> code);
 
   void BuildSpecialFunctionTable();
 
@@ -492,14 +486,15 @@
       Factory::NewFunction(symbol, Factory::null_value());
 
   {  // --- E m p t y ---
-    Handle<Code> call_code =
+    Handle<Code> code =
         Handle<Code>(Builtins::builtin(Builtins::EmptyFunction));
     Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}"));
 
-    empty_function->set_code(*call_code);
+    empty_function->set_code(*code);
     empty_function->shared()->set_script(*Factory::NewScript(source));
     empty_function->shared()->set_start_position(0);
     empty_function->shared()->set_end_position(source->length());
+    empty_function->shared()->DontAdaptArguments();
     global_context()->function_map()->set_prototype(*empty_function);
     global_context()->function_instance_map()->set_prototype(*empty_function);
 
@@ -586,6 +581,7 @@
         InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
                         Top::initial_object_prototype(), Builtins::ArrayCode,
                         true);
+    array_function->shared()->DontAdaptArguments();
 
     // This seems a bit hackish, but we need to make sure Array.length
     // is 1.
@@ -715,6 +711,7 @@
       Factory::NewFunction(Factory::empty_symbol(), JS_OBJECT_TYPE,
                            JSObject::kHeaderSize, code, true);
   global_context()->set_call_as_function_delegate(*delegate);
+  delegate->shared()->DontAdaptArguments();
 
   global_context()->set_special_function_table(Heap::empty_fixed_array());
 
@@ -961,36 +958,38 @@
 
   InstallNativeFunctions();
 
-#ifndef USE_OLD_CALLING_CONVENTIONS
-  // TODO(1240778): Get rid of the JS implementation of
-  // Function.prototype.call and simply create a function with the
-  // faked formal parameter count (-1) and use the illegal builtin as
-  // the code for it.
-
-  // Find Function.prototype.call and set it's number of formal
-  // parameters to -1 to let the arguments adaptor handle it
-  // specially.
-  { Handle<JSFunction> function =
-        Handle<JSFunction>::cast(GetProperty(Top::global(),
-                                             Factory::function_class_symbol()));
+  // Install Function.prototype.call and apply.
+  { Handle<String> key = Factory::function_class_symbol();
+    Handle<JSFunction> function =
+        Handle<JSFunction>::cast(GetProperty(Top::global(), key));
     Handle<JSObject> proto =
         Handle<JSObject>(JSObject::cast(function->instance_prototype()));
+
+    // Install the call and the apply functions.
     Handle<JSFunction> call =
-        Handle<JSFunction>::cast(GetProperty(proto, Factory::call_symbol()));
-    call->shared()->set_formal_parameter_count(-1);
+        InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
+                        Factory::NewJSObject(Top::object_function(), TENURED),
+                        Builtins::FunctionCall,
+                        false);
+    Handle<JSFunction> apply =
+        InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
+                        Factory::NewJSObject(Top::object_function(), TENURED),
+                        Builtins::FunctionApply,
+                        false);
 
     // Make sure that Function.prototype.call appears to be compiled.
     // The code will never be called, but inline caching for call will
     // only work if it appears to be compiled.
-    call->shared()->set_code(Builtins::builtin(Builtins::Illegal));
+    call->shared()->DontAdaptArguments();
     ASSERT(call->is_compiled());
 
-    // Use the specialized builtin for Function.prototype.apply.
-    Handle<JSFunction> apply =
-        Handle<JSFunction>::cast(GetProperty(proto, Factory::apply_symbol()));
-    apply->shared()->set_code(Builtins::builtin(Builtins::FunctionApply));
+    // Set the expected paramters for apply to 2; required by builtin.
+    apply->shared()->set_formal_parameter_count(2);
+
+    // Set the lengths for the functions to satisfy ECMA-262.
+    call->shared()->set_length(1);
+    apply->shared()->set_length(2);
   }
-#endif
 
   // Make sure that the builtins object has fast properties.
   // If the ASSERT below fails, please increase the expected number of
@@ -1269,8 +1268,7 @@
 
 void Genesis::AddSpecialFunction(Handle<JSObject> prototype,
                                  const char* name,
-                                 Handle<Code> code,
-                                 int parameter_count) {
+                                 Handle<Code> code) {
   Handle<String> key = Factory::LookupAsciiSymbol(name);
   Handle<Object> value = Handle<Object>(prototype->GetProperty(*key));
   if (value->IsJSFunction()) {
@@ -1279,7 +1277,7 @@
                                                         JSObject::kHeaderSize,
                                                         code,
                                                         false);
-    optimized->shared()->set_formal_parameter_count(parameter_count);
+    optimized->shared()->DontAdaptArguments();
     int len = global_context()->special_function_table()->length();
     Handle<FixedArray> new_array = Factory::NewFixedArray(len + 3);
     for (int index = 0; index < len; index++) {
@@ -1304,11 +1302,9 @@
   Handle<JSObject> prototype =
       Handle<JSObject>(JSObject::cast(function->prototype()));
   AddSpecialFunction(prototype, "pop",
-                     Handle<Code>(Builtins::builtin(Builtins::ArrayPop)),
-                     0);
+                     Handle<Code>(Builtins::builtin(Builtins::ArrayPop)));
   AddSpecialFunction(prototype, "push",
-                     Handle<Code>(Builtins::builtin(Builtins::ArrayPush)),
-                     1);
+                     Handle<Code>(Builtins::builtin(Builtins::ArrayPush)));
 }
 
 
diff --git a/src/builtins-arm.cc b/src/builtins-arm.cc
index 74f157f..da177ac 100644
--- a/src/builtins-arm.cc
+++ b/src/builtins-arm.cc
@@ -37,79 +37,123 @@
 #define __ masm->
 
 
-void Builtins::Generate_Adaptor(MacroAssembler* masm,
-                                int argc,
-                                CFunctionId id) {
-  // r0 contains the number of arguments excluding the receiver.
-  // JumpToBuiltin expects r0 to contains the number of arguments
-  // including the receiver.
+void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
+  // TODO(1238487): Don't pass the function in a static variable.
+  __ mov(ip, Operand(ExternalReference::builtin_passed_function()));
+  __ str(r1, MemOperand(ip, 0));
+
+  // The actual argument count has already been loaded into register
+  // r0, but JumpToBuiltin expects r0 to contain the number of
+  // arguments including the receiver.
   __ add(r0, r0, Operand(1));
   __ JumpToBuiltin(ExternalReference(id));
 }
 
 
 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
-  // r0: number of arguments
+  // ----------- S t a t e -------------
+  //  -- r0     : number of arguments
+  //  -- r1     : constructor function
+  //  -- lr     : return address
+  //  -- sp[...]: constructor arguments
+  // -----------------------------------
 
-  __ EnterJSFrame(0);
+  // Enter an internal frame.
+  __ EnterInternalFrame();
+
+  // Preserve the two incoming parameters
+  __ mov(r0, Operand(r0, LSL, kSmiTagSize));
+  __ push(r0);  // smi-tagged arguments count
+  __ push(r1);  // constructor function
 
   // Allocate the new receiver object.
-  __ ldr(r0, MemOperand(pp, JavaScriptFrameConstants::kFunctionOffset));
-  __ push(r0);
+  __ push(r1);  // argument for Runtime_NewObject
   __ CallRuntime(Runtime::kNewObject, 1);
   __ push(r0);  // save the receiver
 
   // Push the function and the allocated receiver from the stack.
-  __ ldr(r1, MemOperand(pp, JavaScriptFrameConstants::kFunctionOffset));
+  // sp[0]: receiver (newly allocated object)
+  // sp[1]: constructor function
+  // sp[2]: number of arguments (smi-tagged)
+  __ ldr(r1, MemOperand(sp, kPointerSize));
   __ push(r1);  // function
   __ push(r0);  // receiver
 
-  // Restore the arguments length from the stack.
-  __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kArgsLengthOffset));
+  // Reload the number of arguments from the stack.
+  // r1: constructor function
+  // sp[0]: receiver
+  // sp[1]: constructor function
+  // sp[2]: receiver
+  // sp[3]: constructor function
+  // sp[4]: number of arguments (smi-tagged)
+  __ ldr(r3, MemOperand(sp, 4 * kPointerSize));
 
-  // Setup pointer to last argument - receiver is not counted.
-  __ sub(r2, pp, Operand(r0, LSL, kPointerSizeLog2));
-  __ sub(r2, r2, Operand(kPointerSize));
+  // Setup pointer to last argument.
+  __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
+
+  // Setup number of arguments for function call below
+  __ mov(r0, Operand(r3, LSR, kSmiTagSize));
 
   // Copy arguments and receiver to the expression stack.
+  // r0: number of arguments
+  // r2: address of last argument (caller sp)
+  // r1: constructor function
+  // r3: number of arguments (smi-tagged)
+  // sp[0]: receiver
+  // sp[1]: constructor function
+  // sp[2]: receiver
+  // sp[3]: constructor function
+  // sp[4]: number of arguments (smi-tagged)
   Label loop, entry;
-  __ mov(r1, Operand(r0));
   __ b(&entry);
   __ bind(&loop);
-  __ ldr(r3, MemOperand(r2, r1, LSL, kPointerSizeLog2));
-  __ push(r3);
+  __ ldr(ip, MemOperand(r2, r3, LSL, kPointerSizeLog2 - 1));
+  __ push(ip);
   __ bind(&entry);
-  __ sub(r1, r1, Operand(1), SetCC);
+  __ sub(r3, r3, Operand(2), SetCC);
   __ b(ge, &loop);
 
-  // Get the function to call from the stack.
-  __ ldr(r1, MemOperand(pp, JavaScriptFrameConstants::kFunctionOffset));
-
   // Call the function.
+  // r0: number of arguments
+  // r1: constructor function
   Label return_site;
   __ RecordPosition(position);
   ParameterCount actual(r0);
   __ InvokeFunction(r1, actual, CALL_FUNCTION);
   __ bind(&return_site);
 
-  // Restore context from the frame and discard the function.
-  __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  // Pop the function from the stack.
+  // sp[0]: constructor function
+  // sp[2]: receiver
+  // sp[3]: constructor function
+  // sp[4]: number of arguments (smi-tagged)
   __ pop();
 
+  // Restore context from the frame.
+  // r0: result
+  // sp[0]: receiver
+  // sp[1]: constructor function
+  // sp[2]: number of arguments (smi-tagged)
+  __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+
   // If the result is an object (in the ECMA sense), we should get rid
   // of the receiver and use the result; see ECMA-262 section 13.2.2-7
   // on page 74.
   Label use_receiver, exit;
 
   // If the result is a smi, it is *not* an object in the ECMA sense.
+  // r0: result
+  // sp[0]: receiver (newly allocated object)
+  // sp[1]: constructor function
+  // sp[2]: number of arguments (smi-tagged)
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &use_receiver);
 
   // If the type of the result (stored in its map) is less than
   // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense.
-  __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
-  __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
-  __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE));
+  __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset));
+  __ ldrb(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
+  __ cmp(r3, Operand(FIRST_JS_OBJECT_TYPE));
   __ b(ge, &exit);
 
   // Throw away the result of the constructor invocation and use the
@@ -120,7 +164,15 @@
   // Remove receiver from the stack, remove caller arguments, and
   // return.
   __ bind(&exit);
-  __ ExitJSFrame(RETURN);
+  // r0: result
+  // sp[0]: receiver (newly allocated object)
+  // sp[1]: constructor function
+  // sp[2]: number of arguments (smi-tagged)
+  __ ldr(r1, MemOperand(sp, 2 * kPointerSize));
+  __ ExitInternalFrame();
+  __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1));
+  __ add(sp, sp, Operand(kPointerSize));
+  __ mov(pc, Operand(lr));
 
   // Compute the offset from the beginning of the JSConstructCall
   // builtin code object to the return address after the call.
@@ -139,24 +191,11 @@
   // r4: argv
   // r5-r7, cp may be clobbered
 
-  // Enter the JS frame
-  // compute parameter pointer before making changes
-  __ mov(ip, Operand(sp));  // ip == caller_sp == new pp
+  // Clear the context before we push it when entering the JS frame.
+  __ mov(cp, Operand(0));
 
-  __ mov(r5, Operand(0));  // spare slot to store caller code object during GC
-  __ mov(r6, Operand(0));  // no context
-  __ mov(r7, Operand(0));  // no incoming parameters
-  __ mov(r8, Operand(0));  // caller_pp == NULL for trampoline frames
-  ASSERT(cp.bit() == r8.bit());  // adjust the code otherwise
-
-  // push in reverse order:
-  // code (r5==0), context (r6==0), args_len (r7==0), caller_pp (r8==0),
-  // caller_fp, sp_on_exit (caller_sp), caller_pc
-  __ stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | r8.bit() |
-         fp.bit() | ip.bit() | lr.bit());
-  // Setup new frame pointer.
-  __ add(fp, sp, Operand(-StandardFrameConstants::kCodeOffset));
-  __ mov(pp, Operand(ip));  // setup new parameter pointer
+  // Enter an internal frame.
+  __ EnterInternalFrame();
 
   // Setup the context from the function argument.
   __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
@@ -191,22 +230,21 @@
     __ mov(r9, Operand(r4));
 
   // Invoke the code and pass argc as r0.
+  __ mov(r0, Operand(r3));
   if (is_construct) {
-    __ mov(r0, Operand(r3));
     __ Call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)),
             code_target);
   } else {
-    ParameterCount actual(r3);
+    ParameterCount actual(r0);
     __ InvokeFunction(r1, actual, CALL_FUNCTION);
   }
 
   // Exit the JS frame and remove the parameters (except function), and return.
   // Respect ABI stack constraint.
-  __ add(sp, fp, Operand(StandardFrameConstants::kCallerFPOffset));
-  __ ldm(ia, sp, fp.bit() | sp.bit() | pc.bit());
+  __ ExitInternalFrame();
+  __ mov(pc, lr);
 
   // r0: result
-  // pp: not restored, should not be used anymore
 }
 
 
@@ -220,23 +258,414 @@
 }
 
 
+void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
+  // 1. Make sure we have at least one argument.
+  // r0: actual number of argument
+  { Label done;
+    __ tst(r0, Operand(r0));
+    __ b(ne, &done);
+    __ mov(r2, Operand(Factory::undefined_value()));
+    __ push(r2);
+    __ add(r0, r0, Operand(1));
+    __ bind(&done);
+  }
+
+  // 2. Get the function to call from the stack.
+  // r0: actual number of argument
+  { Label done, non_function, function;
+    __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
+    __ tst(r1, Operand(kSmiTagMask));
+    __ b(eq, &non_function);
+    __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
+    __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
+    __ cmp(r2, Operand(JS_FUNCTION_TYPE));
+    __ b(eq, &function);
+
+    // Non-function called: Clear the function to force exception.
+    __ bind(&non_function);
+    __ mov(r1, Operand(0));
+    __ b(&done);
+
+    // Change the context eagerly because it will be used below to get the
+    // right global object.
+    __ bind(&function);
+    __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
+
+    __ bind(&done);
+  }
+
+  // 3. Make sure first argument is an object; convert if necessary.
+  // r0: actual number of arguments
+  // r1: function
+  { Label call_to_object, use_global_receiver, patch_receiver, done;
+    __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
+    __ ldr(r2, MemOperand(r2, -kPointerSize));
+
+    // r0: actual number of arguments
+    // r1: function
+    // r2: first argument
+    __ tst(r2, Operand(kSmiTagMask));
+    __ b(eq, &call_to_object);
+
+    __ mov(r3, Operand(Factory::null_value()));
+    __ cmp(r2, r3);
+    __ b(eq, &use_global_receiver);
+    __ mov(r3, Operand(Factory::undefined_value()));
+    __ cmp(r2, r3);
+    __ b(eq, &use_global_receiver);
+
+    __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
+    __ ldrb(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
+    __ cmp(r3, Operand(FIRST_JS_OBJECT_TYPE));
+    __ b(lt, &call_to_object);
+    __ cmp(r3, Operand(LAST_JS_OBJECT_TYPE));
+    __ b(le, &done);
+
+    __ bind(&call_to_object);
+    __ EnterInternalFrame();
+
+    // Store number of arguments and function across the call into the runtime.
+    __ mov(r0, Operand(r0, LSL, kSmiTagSize));
+    __ push(r0);
+    __ push(r1);
+
+    __ push(r2);
+    __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
+    __ mov(r2, r0);
+
+    // Restore number of arguments and function.
+    __ pop(r1);
+    __ pop(r0);
+    __ mov(r0, Operand(r0, ASR, kSmiTagSize));
+
+    __ ExitInternalFrame();
+    __ b(&patch_receiver);
+
+    // Use the global object from the called function as the receiver.
+    __ bind(&use_global_receiver);
+    const int kGlobalIndex =
+        Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+    __ ldr(r2, FieldMemOperand(cp, kGlobalIndex));
+
+    __ bind(&patch_receiver);
+    __ add(r3, sp, Operand(r0, LSL, kPointerSizeLog2));
+    __ str(r2, MemOperand(r3, -kPointerSize));
+
+    __ bind(&done);
+  }
+
+  // 4. Shift stuff one slot down the stack
+  // r0: actual number of arguments (including call() receiver)
+  // r1: function
+  { Label loop;
+    // Calculate the copy start address (destination). Copy end address is sp.
+    __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
+    __ add(r2, r2, Operand(kPointerSize));  // copy receiver too
+
+    __ bind(&loop);
+    __ ldr(ip, MemOperand(r2, -kPointerSize));
+    __ str(ip, MemOperand(r2));
+    __ sub(r2, r2, Operand(kPointerSize));
+    __ cmp(r2, sp);
+    __ b(ne, &loop);
+  }
+
+  // 5. Adjust the actual number of arguments and remove the top element.
+  // r0: actual number of arguments (including call() receiver)
+  // r1: function
+  __ sub(r0, r0, Operand(1));
+  __ add(sp, sp, Operand(kPointerSize));
+
+  // 6. Get the code for the function or the non-function builtin.
+  //    If number of expected arguments matches, then call. Otherwise restart
+  //    the arguments adaptor stub.
+  // r0: actual number of arguments
+  // r1: function
+  { Label invoke;
+    __ tst(r1, r1);
+    __ b(ne, &invoke);
+    __ mov(r2, Operand(0));  // expected arguments is 0 for CALL_NON_FUNCTION
+    __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
+    __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), code_target);
+
+    __ bind(&invoke);
+    __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
+    __ ldr(r2,
+           FieldMemOperand(r3,
+                           SharedFunctionInfo::kFormalParameterCountOffset));
+    __ ldr(r3,
+           MemOperand(r3, SharedFunctionInfo::kCodeOffset - kHeapObjectTag));
+    __ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
+    __ cmp(r2, r0);  // Check formal and actual parameter counts.
+    __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), code_target, ne);
+
+    // 7. Jump to the code in r3 without checking arguments.
+    ParameterCount expected(0);
+    __ InvokeCode(r3, expected, expected, JUMP_FUNCTION);
+  }
+}
+
+
 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
-  // TODO(1233523): Implement. Unused for now.
-  __ stop("Builtins::Generate_FunctionApply");
+  const int kIndexOffset    = -5 * kPointerSize;
+  const int kLimitOffset    = -4 * kPointerSize;
+  const int kArgsOffset     =  2 * kPointerSize;
+  const int kRecvOffset     =  3 * kPointerSize;
+  const int kFunctionOffset =  4 * kPointerSize;
+
+  __ EnterInternalFrame();
+
+  __ ldr(r0, MemOperand(fp, kFunctionOffset));  // get the function
+  __ push(r0);
+  __ ldr(r0, MemOperand(fp, kArgsOffset));  // get the args array
+  __ push(r0);
+  __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_JS);
+
+  // Eagerly check for stack-overflow before starting to push the arguments.
+  // r0: number of arguments
+  Label okay;
+  { Label L;
+    __ mov(r1, Operand(391864 << kSmiTagSize));
+    __ cmp(r0, r1);
+    __ b(cc, &L);
+    __ bind(&L);
+  }
+  ExternalReference stack_guard_limit_address =
+      ExternalReference::address_of_stack_guard_limit();
+  __ mov(r2, Operand(stack_guard_limit_address));
+  __ ldr(r2, MemOperand(r2));
+  __ sub(r2, sp, r2);
+  __ sub(r2, r2, Operand(3 * kPointerSize));  // limit, index, receiver
+
+  __ cmp(r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
+  __ b(hi, &okay);
+
+  // Out of stack space.
+  __ ldr(r1, MemOperand(fp, kFunctionOffset));
+  __ push(r1);
+  __ push(r0);
+  __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_JS);
+
+  // Push current limit and index.
+  __ bind(&okay);
+  __ push(r0);  // limit
+  __ mov(r1, Operand(0));  // initial index
+  __ push(r1);
+
+  // Change context eagerly to get the right global object if necessary.
+  __ ldr(r0, MemOperand(fp, kFunctionOffset));
+  __ ldr(cp, FieldMemOperand(r0, JSFunction::kContextOffset));
+
+  // Compute the receiver.
+  Label call_to_object, use_global_receiver, push_receiver;
+  __ ldr(r0, MemOperand(fp, kRecvOffset));
+  __ tst(r0, Operand(kSmiTagMask));
+  __ b(eq, &call_to_object);
+  __ mov(r1, Operand(Factory::null_value()));
+  __ cmp(r0, r1);
+  __ b(eq, &use_global_receiver);
+  __ mov(r1, Operand(Factory::undefined_value()));
+  __ cmp(r0, r1);
+  __ b(eq, &use_global_receiver);
+
+  // Check if the receiver is already a JavaScript object.
+  // r0: receiver
+  __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
+  __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));
+  __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
+  __ b(lt, &call_to_object);
+  __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
+  __ b(le, &push_receiver);
+
+  // Convert the receiver to a regular object.
+  // r0: receiver
+  __ bind(&call_to_object);
+  __ push(r0);
+  __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
+  __ b(&push_receiver);
+
+  // Use the current global object as the receiver.
+  __ bind(&use_global_receiver);
+  __ ldr(r0, FieldMemOperand(cp, Context::kHeaderSize +
+                             Context::GLOBAL_INDEX * kPointerSize));
+
+  // Push the receiver.
+  // r0: receiver
+  __ bind(&push_receiver);
+  __ push(r0);
+
+  // Copy all arguments from the array to the stack.
+  Label entry, loop;
+  __ ldr(r0, MemOperand(fp, kIndexOffset));
+  __ b(&entry);
+
+  // Load the current argument from the arguments array and push it to the
+  // stack.
+  // r0: current argument index
+  __ bind(&loop);
+  __ ldr(r1, MemOperand(fp, kArgsOffset));
+  __ push(r1);
+  __ push(r0);
+
+  // Call the runtime to access the property in the arguments array.
+  __ CallRuntime(Runtime::kGetProperty, 2);
+  __ push(r0);
+
+  // Use inline caching to access the arguments.
+  __ ldr(r0, MemOperand(fp, kIndexOffset));
+  __ add(r0, r0, Operand(1 << kSmiTagSize));
+  __ str(r0, MemOperand(fp, kIndexOffset));
+
+  // Test if the copy loop has finished copying all the elements from the
+  // arguments object.
+  __ bind(&entry);
+  __ ldr(r1, MemOperand(fp, kLimitOffset));
+  __ cmp(r0, r1);
+  __ b(ne, &loop);
+
+  // Invoke the function.
+  ParameterCount actual(r0);
+  __ mov(r0, Operand(r0, ASR, kSmiTagSize));
+  __ ldr(r1, MemOperand(fp, kFunctionOffset));
+  __ InvokeFunction(r1, actual, CALL_FUNCTION);
+
+  // Tear down the internal frame and remove function, receiver and args.
+  __ ExitInternalFrame();
+  __ add(sp, sp, Operand(3 * kPointerSize));
+  __ mov(pc, lr);
+}
+
+
+static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
+  __ mov(r0, Operand(r0, LSL, kSmiTagSize));
+  __ mov(r4, Operand(ArgumentsAdaptorFrame::SENTINEL));
+  __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() | fp.bit() | lr.bit());
+  __ add(fp, sp, Operand(3 * kPointerSize));
+}
+
+
+static void ExitArgumentsAdaptorFrame(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r0 : result being passed through
+  // -----------------------------------
+  // Get the number of arguments passed (as a smi), tear down the frame and
+  // then tear down the parameters.
+  __ ldr(r1, MemOperand(fp, -3 * kPointerSize));
+  __ mov(sp, fp);
+  __ ldm(ia_w, sp, fp.bit() | lr.bit());
+  __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
+  __ add(sp, sp, Operand(kPointerSize));  // adjust for receiver
 }
 
 
 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
-  // TODO(1233523): Implement. Unused for now.
-  __ stop("Builtins::Generate_ArgumentsAdaptorTrampoline");
+  // ----------- S t a t e -------------
+  //  -- r0 : actual number of arguments
+  //  -- r1 : function (passed through to callee)
+  //  -- r2 : expected number of arguments
+  //  -- r3 : code entry to call
+  // -----------------------------------
 
+  Label invoke, dont_adapt_arguments;
+
+  Label enough, too_few;
+  __ cmp(r0, Operand(r2));
+  __ b(lt, &too_few);
+  __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
+  __ b(eq, &dont_adapt_arguments);
+
+  {  // Enough parameters: actual >= excpected
+    __ bind(&enough);
+    EnterArgumentsAdaptorFrame(masm);
+
+    // Calculate copy start address into r0 and copy end address into r2.
+    // r0: actual number of arguments as a smi
+    // r1: function
+    // r2: expected number of arguments
+    // r3: code entry to call
+    __ add(r0, fp, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
+    // adjust for return address and receiver
+    __ add(r0, r0, Operand(2 * kPointerSize));
+    __ sub(r2, r0, Operand(r2, LSL, kPointerSizeLog2));
+
+    // Copy the arguments (including the receiver) to the new stack frame.
+    // r0: copy start address
+    // r1: function
+    // r2: copy end address
+    // r3: code entry to call
+
+    Label copy;
+    __ bind(&copy);
+    __ ldr(ip, MemOperand(r0, 0));
+    __ push(ip);
+    __ cmp(r0, r2);  // Compare before moving to next argument.
+    __ sub(r0, r0, Operand(kPointerSize));
+    __ b(ne, &copy);
+
+    __ b(&invoke);
+  }
+
+  {  // Too few parameters: Actual < expected
+    __ bind(&too_few);
+    EnterArgumentsAdaptorFrame(masm);
+
+    // Calculate copy start address into r0 and copy end address is fp.
+    // r0: actual number of arguments as a smi
+    // r1: function
+    // r2: expected number of arguments
+    // r3: code entry to call
+    __ add(r0, fp, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
+
+    // Copy the arguments (including the receiver) to the new stack frame.
+    // r0: copy start address
+    // r1: function
+    // r2: expected number of arguments
+    // r3: code entry to call
+    Label copy;
+    __ bind(&copy);
+    // Adjust load for return address and receiver.
+    __ ldr(ip, MemOperand(r0, 2 * kPointerSize));
+    __ push(ip);
+    __ cmp(r0, fp);  // Compare before moving to next argument.
+    __ sub(r0, r0, Operand(kPointerSize));
+    __ b(ne, &copy);
+
+    // Fill the remaining expected arguments with undefined.
+    // r1: function
+    // r2: expected number of arguments
+    // r3: code entry to call
+    __ mov(ip, Operand(Factory::undefined_value()));
+    __ sub(r2, fp, Operand(r2, LSL, kPointerSizeLog2));
+    __ sub(r2, r2, Operand(4 * kPointerSize));  // Adjust for frame.
+
+    Label fill;
+    __ bind(&fill);
+    __ push(ip);
+    __ cmp(sp, r2);
+    __ b(ne, &fill);
+  }
+
+  // Call the entry point.
   Label return_site;
+  __ bind(&invoke);
+
+  __ Call(r3);
   __ bind(&return_site);
 
+  ExitArgumentsAdaptorFrame(masm);
+  __ mov(pc, lr);
+
   // Compute the offset from the beginning of the ArgumentsAdaptorTrampoline
   // builtin code object to the return address after the call.
   ASSERT(return_site.is_bound());
   arguments_adaptor_call_pc_offset_ = return_site.pos() + Code::kHeaderSize;
+
+
+  // -------------------------------------------
+  // Dont adapt arguments.
+  // -------------------------------------------
+  __ bind(&dont_adapt_arguments);
+  __ mov(pc, r3);
 }
 
 
diff --git a/src/builtins-ia32.cc b/src/builtins-ia32.cc
index bf63464..dbf8c5c 100644
--- a/src/builtins-ia32.cc
+++ b/src/builtins-ia32.cc
@@ -37,25 +37,27 @@
 #define __ masm->
 
 
-void Builtins::Generate_Adaptor(MacroAssembler* masm,
-                                int argc,
-                                CFunctionId id) {
-  // argc is the number of arguments excluding the receiver.
-  // JumpToBuiltin expects eax to contain the number of arguments
-  // including the receiver.
-  __ mov(eax, argc + 1);
-  __ mov(Operand::StaticVariable(ExternalReference::builtin_passed_function()),
-         edi);
+void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
+  // TODO(1238487): Don't pass the function in a static variable.
+  ExternalReference passed = ExternalReference::builtin_passed_function();
+  __ mov(Operand::StaticVariable(passed), edi);
+
+  // The actual argument count has already been loaded into register
+  // eax, but JumpToBuiltin expects eax to contain the number of
+  // arguments including the receiver.
+  __ inc(eax);
   __ JumpToBuiltin(ExternalReference(id));
 }
 
 
-DEFINE_bool(inline_new, true, "use fast inline allocation");
-
-
 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- eax: number of arguments
+  //  -- edi: constructor function
+  // -----------------------------------
+
   // Enter an internal frame.
-  __ EnterFrame(StackFrame::INTERNAL);
+  __ EnterInternalFrame();
 
   // Store a smi-tagged arguments count on the stack.
   __ shl(eax, kSmiTagSize);
@@ -296,7 +298,7 @@
   // Restore the arguments count and exit the internal frame.
   __ bind(&exit);
   __ mov(ebx, Operand(esp, kPointerSize));  // get arguments count
-  __ ExitFrame(StackFrame::INTERNAL);
+  __ ExitInternalFrame();
 
   // Remove caller arguments from the stack and return.
   ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
@@ -318,7 +320,7 @@
   __ xor_(esi, Operand(esi));  // clear esi
 
   // Enter an internal frame.
-  __ EnterFrame(StackFrame::INTERNAL);
+  __ EnterInternalFrame();
 
   // Load the previous frame pointer (ebx) to access C arguments
   __ mov(ebx, Operand(ebp, 0));
@@ -362,7 +364,7 @@
   // Exit the JS frame. Notice that this also removes the empty
   // context and the function left on the stack by the code
   // invocation.
-  __ ExitFrame(StackFrame::INTERNAL);
+  __ ExitInternalFrame();
   __ ret(1 * kPointerSize);  // remove receiver
 }
 
@@ -377,8 +379,137 @@
 }
 
 
+void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
+  // 1. Make sure we have at least one argument.
+  { Label done;
+    __ test(eax, Operand(eax));
+    __ j(not_zero, &done, taken);
+    __ pop(ebx);
+    __ push(Immediate(Factory::undefined_value()));
+    __ push(ebx);
+    __ inc(eax);
+    __ bind(&done);
+  }
+
+  // 2. Get the function to call from the stack.
+  { Label done, non_function, function;
+    // +1 ~ return address.
+    __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize));
+    __ test(edi, Immediate(kSmiTagMask));
+    __ j(zero, &non_function, not_taken);
+    __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));  // get the map
+    __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
+    __ cmp(ecx, JS_FUNCTION_TYPE);
+    __ j(equal, &function, taken);
+
+    // Non-function called: Clear the function to force exception.
+    __ bind(&non_function);
+    __ xor_(edi, Operand(edi));
+    __ jmp(&done);
+
+    // Function called: Change context eagerly to get the right global object.
+    __ bind(&function);
+    __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
+
+    __ bind(&done);
+  }
+
+  // 3. Make sure first argument is an object; convert if necessary.
+  { Label call_to_object, use_global_receiver, patch_receiver, done;
+    __ mov(ebx, Operand(esp, eax, times_4, 0));
+
+    __ test(ebx, Immediate(kSmiTagMask));
+    __ j(zero, &call_to_object);
+
+    __ cmp(ebx, Factory::null_value());
+    __ j(equal, &use_global_receiver);
+    __ cmp(ebx, Factory::undefined_value());
+    __ j(equal, &use_global_receiver);
+
+    __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
+    __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
+    __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
+    __ j(less, &call_to_object);
+    __ cmp(ecx, LAST_JS_OBJECT_TYPE);
+    __ j(less_equal, &done);
+
+    __ bind(&call_to_object);
+    __ EnterInternalFrame();  // preserves eax, ebx, edi
+
+    // Store the arguments count on the stack (smi tagged).
+    ASSERT(kSmiTag == 0);
+    __ shl(eax, kSmiTagSize);
+    __ push(eax);
+
+    __ push(edi);  // save edi across the call
+    __ push(ebx);
+    __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+    __ mov(Operand(ebx), eax);
+    __ pop(edi);  // restore edi after the call
+
+    // Get the arguments count and untag it.
+    __ pop(eax);
+    __ shr(eax, kSmiTagSize);
+
+    __ ExitInternalFrame();
+    __ jmp(&patch_receiver);
+
+    // Use the global object from the called function as the receiver.
+    __ bind(&use_global_receiver);
+    const int kGlobalIndex =
+        Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
+    __ mov(ebx, FieldOperand(esi, kGlobalIndex));
+
+    __ bind(&patch_receiver);
+    __ mov(Operand(esp, eax, times_4, 0), ebx);
+
+    __ bind(&done);
+  }
+
+  // 4. Shift stuff one slot down the stack.
+  { Label loop;
+    __ lea(ecx, Operand(eax, +1));  // +1 ~ copy receiver too
+    __ bind(&loop);
+    __ mov(ebx, Operand(esp, ecx, times_4, 0));
+    __ mov(Operand(esp, ecx, times_4, kPointerSize), ebx);
+    __ dec(ecx);
+    __ j(not_zero, &loop);
+  }
+
+  // 5. Remove TOS (copy of last arguments), but keep return address.
+  __ pop(ebx);
+  __ pop(ecx);
+  __ push(ebx);
+  __ dec(eax);
+
+  // 6. Check that function really was a function and get the code to
+  //    call from the function and check that the number of expected
+  //    arguments matches what we're providing.
+  { Label invoke;
+    __ test(edi, Operand(edi));
+    __ j(not_zero, &invoke, taken);
+    __ xor_(ebx, Operand(ebx));
+    __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
+    __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), code_target);
+
+    __ bind(&invoke);
+    __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
+    __ mov(ebx,
+           FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
+    __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
+    __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
+    __ cmp(eax, Operand(ebx));
+    __ j(not_equal, Handle<Code>(builtin(ArgumentsAdaptorTrampoline)));
+  }
+
+  // 7. Jump (tail-call) to the code in register edx without checking arguments.
+  ParameterCount expected(0);
+  __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
+}
+
+
 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
-  __ EnterFrame(StackFrame::INTERNAL);
+  __ EnterInternalFrame();
 
   __ push(Operand(ebp, 4 * kPointerSize));  // push this
   __ push(Operand(ebp, 2 * kPointerSize));  // push arguments
@@ -482,7 +613,7 @@
   __ mov(edi, Operand(ebp, 4 * kPointerSize));
   __ InvokeFunction(edi, actual, CALL_FUNCTION);
 
-  __ ExitFrame(StackFrame::INTERNAL);
+  __ ExitInternalFrame();
   __ ret(3 * kPointerSize);  // remove this, receiver, and arguments
 }
 
@@ -528,15 +659,14 @@
   //  -- edx : code entry to call
   // -----------------------------------
 
-  Label entry, invoke, function_prototype_call;
-  __ bind(&entry);
+  Label invoke, dont_adapt_arguments;
   __ IncrementCounter(&Counters::arguments_adaptors, 1);
 
   Label enough, too_few;
   __ cmp(eax, Operand(ebx));
   __ j(less, &too_few);
-  __ cmp(ebx, -1);
-  __ j(equal, &function_prototype_call);
+  __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
+  __ j(equal, &dont_adapt_arguments);
 
   {  // Enough parameters: Actual >= expected.
     __ bind(&enough);
@@ -586,8 +716,7 @@
     __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
   }
 
-  // Mark the adaptor frame as special by overwriting the context slot
-  // in the stack with a sentinel.
+  // Call the entry point.
   Label return_site;
   __ bind(&invoke);
   __ call(Operand(edx));
@@ -603,135 +732,10 @@
 
 
   // -------------------------------------------
-  // Function.prototype.call implementation.
+  // Dont adapt arguments.
   // -------------------------------------------
-  __ bind(&function_prototype_call);
-
-  // 1. Make sure we have at least one argument.
-  { Label done;
-    __ test(eax, Operand(eax));
-    __ j(not_zero, &done, taken);
-    __ pop(ebx);
-    __ push(Immediate(Factory::undefined_value()));
-    __ push(ebx);
-    __ inc(eax);
-    __ bind(&done);
-  }
-
-  // 2. Get the function to call from the stack.
-  { Label done, non_function, function;
-    // +1 ~ return address.
-    __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize));
-    __ test(edi, Immediate(kSmiTagMask));
-    __ j(zero, &non_function, not_taken);
-    __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));  // get the map
-    __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
-    __ cmp(ecx, JS_FUNCTION_TYPE);
-    __ j(equal, &function, taken);
-
-    // Non-function called: Clear the function to force exception.
-    __ bind(&non_function);
-    __ xor_(edi, Operand(edi));
-    __ jmp(&done);
-
-    // Function called: Change context eagerly to get the right global object.
-    __ bind(&function);
-    __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
-
-    __ bind(&done);
-  }
-
-  // 3. Make sure first argument is an object; convert if necessary.
-  { Label call_to_object, use_global_receiver, patch_receiver, done;
-    __ mov(ebx, Operand(esp, eax, times_4, 0));
-
-    __ test(ebx, Immediate(kSmiTagMask));
-    __ j(zero, &call_to_object);
-
-    __ cmp(ebx, Factory::null_value());
-    __ j(equal, &use_global_receiver);
-    __ cmp(ebx, Factory::undefined_value());
-    __ j(equal, &use_global_receiver);
-
-    __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
-    __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
-    __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
-    __ j(less, &call_to_object);
-    __ cmp(ecx, LAST_JS_OBJECT_TYPE);
-    __ j(less_equal, &done);
-
-    __ bind(&call_to_object);
-    __ EnterFrame(StackFrame::INTERNAL);  // preserves eax, ebx, edi
-
-    // Store the arguments count on the stack (smi tagged).
-    ASSERT(kSmiTag == 0);
-    __ shl(eax, kSmiTagSize);
-    __ push(eax);
-
-    __ push(edi);  // save edi across the call
-    __ push(ebx);
-    __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
-    __ mov(Operand(ebx), eax);
-    __ pop(edi);  // restore edi after the call
-
-    // Get the arguments count and untag it.
-    __ pop(eax);
-    __ shr(eax, kSmiTagSize);
-
-    __ ExitFrame(StackFrame::INTERNAL);
-    __ jmp(&patch_receiver);
-
-    // Use the global object from the called function as the receiver.
-    __ bind(&use_global_receiver);
-    const int kGlobalIndex =
-        Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
-    __ mov(ebx, FieldOperand(esi, kGlobalIndex));
-
-    __ bind(&patch_receiver);
-    __ mov(Operand(esp, eax, times_4, 0), ebx);
-
-    __ bind(&done);
-  }
-
-  // 4. Shift stuff one slot down the stack.
-  { Label loop;
-    __ lea(ecx, Operand(eax, +1));  // +1 ~ copy receiver too
-    __ bind(&loop);
-    __ mov(ebx, Operand(esp, ecx, times_4, 0));
-    __ mov(Operand(esp, ecx, times_4, kPointerSize), ebx);
-    __ dec(ecx);
-    __ j(not_zero, &loop);
-  }
-
-  // 5. Remove TOS (copy of last arguments), but keep return address.
-  __ pop(ebx);
-  __ pop(ecx);
-  __ push(ebx);
-  __ dec(eax);
-
-  // 6. Check that function really was a function and get the code to
-  //    call from the function and check that the number of expected
-  //    arguments matches what we're providing.
-  { Label invoke;
-    __ test(edi, Operand(edi));
-    __ j(not_zero, &invoke, taken);
-    __ xor_(ebx, Operand(ebx));
-    __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
-    __ jmp(&enough);
-
-    __ bind(&invoke);
-    __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
-    __ mov(ebx,
-           FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
-    __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
-    __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
-    __ cmp(eax, Operand(ebx));
-    __ j(not_equal, &entry);
-  }
-
-  // 7. Jump (tail-call) to the code in register edx without checking arguments.
-  ParameterCount expected(0);
-  __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
+  __ bind(&dont_adapt_arguments);
+  __ jmp(Operand(edx));
 }
 
 
@@ -747,7 +751,7 @@
   __ SaveRegistersToMemory(kJSCallerSaved);
 
   // Enter an internal frame.
-  __ EnterFrame(StackFrame::INTERNAL);
+  __ EnterInternalFrame();
 
   // Store the registers containing object pointers on the expression stack to
   // make sure that these are correctly updated during GC.
@@ -767,7 +771,7 @@
   __ PopRegistersToMemory(pointer_regs);
 
   // Get rid of the internal frame.
-  __ ExitFrame(StackFrame::INTERNAL);
+  __ ExitInternalFrame();
 
   // If this call did not replace a call but patched other code then there will
   // be an unwanted return address left on the stack. Here we get rid of that.
diff --git a/src/builtins.cc b/src/builtins.cc
index 02f3d8a..4b79b27 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -34,27 +34,19 @@
 
 namespace v8 { namespace internal {
 
-#ifdef DEBUG
-  DECLARE_bool(print_builtin_code);
-#endif  // DEBUG
-
-
 // ----------------------------------------------------------------------------
 // Support macros for defining builtins in C.
 // ----------------------------------------------------------------------------
 //
 // A builtin function is defined by writing:
 //
-//   BUILTIN_<n>(name, ...)
-//   {
+//   BUILTIN(name) {
 //     ...
 //   }
 //   BUILTIN_END
 //
-// where <n> is the number of arguments (not counting the receiver). The
-// names of the arguments must be listed after the name in the declaration.
-// In the body of the builtin function, the variables 'env' and 'receiver'
-// are visible. The arguments can be accessed through:
+// In the body of the builtin function, the variable 'receiver' is visible.
+// The arguments can be accessed through:
 //
 //   BUILTIN_ARG(0): Receiver (also available as 'receiver')
 //   BUILTIN_ARG(1): First argument
@@ -68,51 +60,12 @@
 // ----------------------------------------------------------------------------
 
 
-// TODO(1238487): This is not okay. We need to get rid of this macro
-// and start calling the builtins in a more direct way. Looking at the
-// stack frames for all builtin invocations comes with a pretty
-// significant performance penalty.
-#define BUILTIN_0(name)                                                 \
-  static Object* Builtin_##name(int __argc__,                           \
-                                Object** __argv__) {                    \
-    Handle<Object> receiver(&__argv__[0]);                              \
-    bool is_construct = false;                                          \
-    USE(__argc__);                                                      \
-    USE(__argv__);                                                      \
-    { StackFrameIterator it;                                            \
-      ASSERT(it.frame()->is_exit());                                    \
-      it.Advance();                                                     \
-      StackFrame::Type type = it.frame()->type();                       \
-      if (type == StackFrame::INTERNAL) {                               \
-        InternalFrame* frame = InternalFrame::cast(it.frame());         \
-        is_construct = frame->is_construct_trampoline();                \
-      } else if (type == StackFrame::ARGUMENTS_ADAPTOR) {               \
-        ArgumentsAdaptorFrame* frame =                                  \
-            ArgumentsAdaptorFrame::cast(it.frame());                    \
-        /* __argc__ includes the receiver. */                           \
-        __argc__ = frame->GetProvidedParametersCount() + 1;             \
-        __argv__ = reinterpret_cast<Object**>(frame->pp()) - 1;         \
-        it.Advance();                                                   \
-        is_construct =                                                  \
-            it.frame()->is_internal() &&                                \
-            InternalFrame::cast(it.frame())->is_construct_trampoline(); \
-      }                                                                 \
-    }
-
-
-#define BUILTIN_1(name, a0)     \
-  BUILTIN_0(name)               \
-  Object* a0 = BUILTIN_ARG(1);
-
-
-#define BUILTIN_2(name, a0, a1)  \
-  BUILTIN_1(name, a0)            \
-  Object* a1 = BUILTIN_ARG(2);
-
-
-#define BUILTIN_3(name, a0, a1, a2)  \
-  BUILTIN_2(name, a0, a1)            \
-  Object* a2 = BUILTIN_ARG(3);
+// TODO(1238487): We should consider passing whether or not the
+// builtin was invoked as a constructor as part of the
+// arguments. Maybe we also want to pass the called function?
+#define BUILTIN(name)                                                   \
+  static Object* Builtin_##name(int __argc__, Object** __argv__) {      \
+    Handle<Object> receiver(&__argv__[0]);
 
 
 // Use an inline function to avoid evaluating the index (n) more than
@@ -133,6 +86,19 @@
 }
 
 
+// TODO(1238487): Get rid of this function that determines if the
+// builtin is called as a constructor. This may be a somewhat slow
+// operation due to the stack frame iteration.
+static inline bool CalledAsConstructor() {
+  StackFrameIterator it;
+  ASSERT(it.frame()->is_exit());
+  it.Advance();
+  StackFrame* frame = it.frame();
+  return frame->is_internal() &&
+      InternalFrame::cast(frame)->is_construct_trampoline();
+}
+
+
 // ----------------------------------------------------------------------------
 
 
@@ -155,20 +121,42 @@
 }
 
 
-BUILTIN_0(Illegal) {
+Handle<Code> Builtins::GetCode(JavaScript id, bool* resolved) {
+  Code* code = Builtins::builtin(Builtins::Illegal);
+  *resolved = false;
+
+  if (Top::security_context() != NULL) {
+    Object* object = Top::security_context_builtins()->javascript_builtin(id);
+    if (object->IsJSFunction()) {
+      Handle<JSFunction> function(JSFunction::cast(object));
+      // Make sure the number of parameters match the formal parameter count.
+      ASSERT(function->shared()->formal_parameter_count() ==
+             Builtins::GetArgumentsCount(id));
+      if (function->is_compiled() || CompileLazy(function, CLEAR_EXCEPTION)) {
+        code = function->code();
+        *resolved = true;
+      }
+    }
+  }
+
+  return Handle<Code>(code);
+}
+
+
+BUILTIN(Illegal) {
   UNREACHABLE();
 }
 BUILTIN_END
 
 
-BUILTIN_0(EmptyFunction) {
+BUILTIN(EmptyFunction) {
 }
 BUILTIN_END
 
 
-BUILTIN_0(ArrayCode) {
+BUILTIN(ArrayCode) {
   JSArray* array;
-  if (is_construct) {
+  if (CalledAsConstructor()) {
     array = JSArray::cast(*receiver);
   } else {
     // Allocate the JS Array
@@ -224,7 +212,7 @@
 BUILTIN_END
 
 
-BUILTIN_0(ArrayPush) {
+BUILTIN(ArrayPush) {
   JSArray* array = JSArray::cast(*receiver);
   ASSERT(array->HasFastElements());
 
@@ -263,7 +251,7 @@
 BUILTIN_END
 
 
-BUILTIN_0(ArrayPop) {
+BUILTIN(ArrayPop) {
   JSArray* array = JSArray::cast(*receiver);
   ASSERT(array->HasFastElements());
   Object* undefined = Heap::undefined_value();
@@ -348,19 +336,15 @@
 }
 
 
-BUILTIN_0(HandleApiCall) {
+BUILTIN(HandleApiCall) {
   HandleScope scope;
+  bool is_construct = CalledAsConstructor();
 
   // TODO(1238487): This is not nice. We need to get rid of this
   // kludgy behavior and start handling API calls in a more direct
   // way - maybe compile specialized stubs lazily?.
-#ifdef USE_OLD_CALLING_CONVENTIONS
-  Handle<JSFunction> function =
-      Handle<JSFunction>(JSFunction::cast(__argv__[1]));
-#else
   Handle<JSFunction> function =
       Handle<JSFunction>(JSFunction::cast(Builtins::builtin_passed_function));
-#endif
 
   if (is_construct) {
     Handle<FunctionTemplateInfo> desc =
@@ -433,9 +417,9 @@
 
 // Handle calls to non-function objects created through the API that
 // support calls.
-BUILTIN_0(HandleApiCallAsFunction) {
+BUILTIN(HandleApiCallAsFunction) {
   // Non-functions are never called as constructors.
-  ASSERT(!is_construct);
+  ASSERT(!CalledAsConstructor());
 
   // Get the object called.
   JSObject* obj = JSObject::cast(*receiver);
@@ -468,7 +452,7 @@
         data,
         self,
         callee,
-        is_construct,
+        false,
         reinterpret_cast<void**>(__argv__ - 1),
         __argc__ - 1);
     v8::Handle<v8::Value> value;
@@ -600,7 +584,7 @@
 Object* Builtins::builtins_[builtin_count] = { NULL, };
 const char* Builtins::names_[builtin_count] = { NULL, };
 
-#define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name),
+#define DEF_ENUM_C(name) FUNCTION_ADDR(Builtin_##name),
   Address Builtins::c_functions_[cfunction_count] = {
     BUILTIN_LIST_C(DEF_ENUM_C)
   };
@@ -631,16 +615,14 @@
     const char* s_name;  // name is only used for generating log information.
     int name;
     Code::Flags flags;
-    int argc;
   };
 
-#define DEF_FUNCTION_PTR_C(name, argc)   \
+#define DEF_FUNCTION_PTR_C(name)         \
     { FUNCTION_ADDR(Generate_Adaptor),   \
       FUNCTION_ADDR(Builtin_##name),     \
       #name,                             \
       c_##name,                          \
-      Code::ComputeFlags(Code::BUILTIN), \
-      argc                               \
+      Code::ComputeFlags(Code::BUILTIN)  \
     },
 
 #define DEF_FUNCTION_PTR_A(name, kind, state) \
@@ -648,8 +630,7 @@
       NULL,                                   \
       #name,                                  \
       name,                                   \
-      Code::ComputeFlags(Code::kind, state),  \
-      -1                                      \
+      Code::ComputeFlags(Code::kind, state)   \
     },
 
   // Define array of pointers to generators and C builtin functions.
@@ -657,7 +638,7 @@
       BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
       BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
       // Terminator:
-      { NULL, NULL, NULL, builtin_count, static_cast<Code::Flags>(0), -1}
+      { NULL, NULL, NULL, builtin_count, static_cast<Code::Flags>(0) }
   };
 
 #undef DEF_FUNCTION_PTR_C
@@ -673,12 +654,12 @@
     if (create_heap_objects) {
       MacroAssembler masm(buffer, sizeof buffer);
       // Generate the code/adaptor.
-      typedef void (*Generator)(MacroAssembler*, int, int);
+      typedef void (*Generator)(MacroAssembler*, int);
       Generator g = FUNCTION_CAST<Generator>(functions[i].generator);
       // We pass all arguments to the generator, but it may not use all of
       // them.  This works because the first arguments are on top of the
       // stack.
-      g(&masm, functions[i].argc, functions[i].name);
+      g(&masm, functions[i].name);
       // Move the code into the object heap.
       CodeDesc desc;
       masm.GetCode(&desc);
diff --git a/src/builtins.h b/src/builtins.h
index 13bd3d5..f7e7773 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -28,24 +28,21 @@
 #ifndef V8_BUILTINS_H_
 #define V8_BUILTINS_H_
 
-
-
 namespace v8 { namespace internal {
 
-
 // Define list of builtins implemented in C.
 #define BUILTIN_LIST_C(V)                          \
-  V(Illegal, 0)                                    \
+  V(Illegal)                                       \
                                                    \
-  V(EmptyFunction, 0)                              \
+  V(EmptyFunction)                                 \
                                                    \
-  V(ArrayCode, 0)                                  \
+  V(ArrayCode)                                     \
                                                    \
-  V(ArrayPush, 1)                                  \
-  V(ArrayPop, 0)                                   \
+  V(ArrayPush)                                     \
+  V(ArrayPop)                                      \
                                                    \
-  V(HandleApiCall, 0)                              \
-  V(HandleApiCallAsFunction, 0)
+  V(HandleApiCall)                                 \
+  V(HandleApiCallAsFunction)
 
 
 // Define list of builtins implemented in assembly.
@@ -90,6 +87,7 @@
   V(KeyedStoreIC_DebugBreak,    KEYED_STORE_IC, DEBUG_BREAK)   \
                                                                \
   /* Uses KeyedLoadIC_Initialize; must be after in list. */    \
+  V(FunctionCall,               BUILTIN, UNINITIALIZED)        \
   V(FunctionApply,              BUILTIN, UNINITIALIZED)
 
 
@@ -143,7 +141,7 @@
   static const char* Lookup(byte* pc);
 
   enum Name {
-#define DEF_ENUM_C(name, ignore) name,
+#define DEF_ENUM_C(name) name,
 #define DEF_ENUM_A(name, kind, state) name,
     BUILTIN_LIST_C(DEF_ENUM_C)
     BUILTIN_LIST_A(DEF_ENUM_A)
@@ -153,7 +151,7 @@
   };
 
   enum CFunctionId {
-#define DEF_ENUM_C(name, ignore) c_##name,
+#define DEF_ENUM_C(name) c_##name,
     BUILTIN_LIST_C(DEF_ENUM_C)
 #undef DEF_ENUM_C
     cfunction_count
@@ -185,6 +183,7 @@
 
   static const char* GetName(JavaScript id) { return javascript_names_[id]; }
   static int GetArgumentsCount(JavaScript id) { return javascript_argc_[id]; }
+  static Handle<Code> GetCode(JavaScript id, bool* resolved);
   static int NumberOfJavaScriptBuiltins() { return id_count; }
 
   // Called from stub-cache.cc.
@@ -201,7 +200,6 @@
   // function f, we use an Object* array here.
   static Object* builtins_[builtin_count];
   static const char* names_[builtin_count];
-
   static const char* javascript_names_[id_count];
   static int javascript_argc_[id_count];
 
@@ -211,13 +209,13 @@
   static int construct_call_pc_offset_;
   static int arguments_adaptor_call_pc_offset_;
 
-  static void Generate_Adaptor(MacroAssembler* masm,
-                               int argc,
-                               CFunctionId id);
+  static void Generate_Adaptor(MacroAssembler* masm, CFunctionId id);
   static void Generate_JSConstructCall(MacroAssembler* masm);
   static void Generate_JSEntryTrampoline(MacroAssembler* masm);
   static void Generate_JSConstructEntryTrampoline(MacroAssembler* masm);
   static void Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm);
+
+  static void Generate_FunctionCall(MacroAssembler* masm);
   static void Generate_FunctionApply(MacroAssembler* masm);
 
   static void Generate_LoadIC_DebugBreak(MacroAssembler* masm);
@@ -230,7 +228,6 @@
   static void Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm);
 };
 
-
 } }  // namespace v8::internal
 
 #endif  // V8_BUILTINS_H_
diff --git a/src/checks.cc b/src/checks.cc
index c01c9b2..2f25456 100644
--- a/src/checks.cc
+++ b/src/checks.cc
@@ -34,14 +34,6 @@
 
 using namespace v8::internal;
 
-DEFINE_bool(stack_trace_on_abort, true,
-            "print a stack trace if an assertion failure occurs");
-
-#ifdef DEBUG
-DEFINE_bool(enable_slow_asserts, false,
-            "enable asserts that are slow to execute");
-#endif
-
 static int fatal_error_handler_nesting_depth = 0;
 
 // Contains protection against recursive calls (faults while handling faults).
diff --git a/src/checks.h b/src/checks.h
index 9dd45ce..3908ab4 100644
--- a/src/checks.h
+++ b/src/checks.h
@@ -32,10 +32,6 @@
 
 #include "flags.h"
 
-#ifdef DEBUG
-DECLARE_bool(enable_slow_asserts);
-#endif  // DEBUG
-
 extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
 void API_Fatal(const char* location, const char* format, ...);
 
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index ebc30ae..e98c158 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -34,10 +34,6 @@
 
 namespace v8 { namespace internal {
 
-#ifdef DEBUG
-DEFINE_bool(print_code_stubs, false, "print code stubs");
-#endif
-
 Handle<Code> CodeStub::GetCode() {
   uint32_t key = GetKey();
   int index = Heap::code_stubs()->FindNumberEntry(key);
diff --git a/src/codegen-arm.cc b/src/codegen-arm.cc
index fa58084..9a17746 100644
--- a/src/codegen-arm.cc
+++ b/src/codegen-arm.cc
@@ -37,34 +37,6 @@
 
 namespace v8 { namespace internal {
 
-DEFINE_bool(trace, false, "trace function calls");
-DECLARE_bool(debug_info);
-DECLARE_bool(debug_code);
-
-#ifdef ENABLE_DISASSEMBLER
-DEFINE_bool(print_code, false, "print generated code");
-#endif
-
-#ifdef DEBUG
-DECLARE_bool(gc_greedy);
-DEFINE_bool(trace_codegen, false,
-            "print name of functions for which code is generated");
-DEFINE_bool(print_builtin_code, false, "print generated code for builtins");
-DEFINE_bool(print_source, false, "pretty print source code");
-DEFINE_bool(print_builtin_source, false,
-            "pretty print source code for builtins");
-DEFINE_bool(print_ast, false, "print source AST");
-DEFINE_bool(print_builtin_ast, false, "print source AST for builtins");
-DEFINE_bool(trace_calls, false, "trace calls");
-DEFINE_bool(trace_builtin_calls, false, "trace builtins calls");
-DEFINE_string(stop_at, "", "function name where to insert a breakpoint");
-#endif  // DEBUG
-
-
-DEFINE_bool(check_stack, true,
-            "check stack for overflow, interrupt, breakpoint");
-
-
 class ArmCodeGenerator;
 
 
@@ -101,35 +73,46 @@
 };
 
 
-// -----------------------------------------------------------------------------
+// -------------------------------------------------------------------------
 // Code generation state
 
+// The state is passed down the AST by the code generator.  It is passed
+// implicitly (in a member variable) to the non-static code generator member
+// functions, and explicitly (as an argument) to the static member functions
+// and the AST node member functions.
+//
+// The state is threaded through the call stack.  Constructing a state
+// implicitly pushes it on the owning code generator's stack of states, and
+// destroying one implicitly pops it.
+
 class CodeGenState BASE_EMBEDDED {
  public:
   enum AccessType {
     UNDEFINED,
     LOAD,
-    LOAD_TYPEOF_EXPR,
-    STORE,
-    INIT_CONST
+    LOAD_TYPEOF_EXPR
   };
 
-  CodeGenState()
-      : access_(UNDEFINED),
-        ref_(NULL),
-        true_target_(NULL),
-        false_target_(NULL) {
-  }
+  // Create an initial code generator state.  Destroying the initial state
+  // leaves the code generator with a NULL state.
+  explicit CodeGenState(ArmCodeGenerator* owner);
 
-  CodeGenState(AccessType access,
-               Reference* ref,
+  // Create a code generator state based on a code generator's current
+  // state.  The new state has its own access type and pair of branch
+  // labels, and no reference.
+  CodeGenState(ArmCodeGenerator* owner,
+               AccessType access,
                Label* true_target,
-               Label* false_target)
-      : access_(access),
-        ref_(ref),
-        true_target_(true_target),
-        false_target_(false_target) {
-  }
+               Label* false_target);
+
+  // Create a code generator state based on a code generator's current
+  // state.  The new state has an access type of LOAD, its own reference,
+  // and inherits the pair of branch labels of the current state.
+  CodeGenState(ArmCodeGenerator* owner, Reference* ref);
+
+  // Destroy a code generator state and restore the owning code generator's
+  // previous state.
+  ~CodeGenState();
 
   AccessType access() const { return access_; }
   Reference* ref() const { return ref_; }
@@ -137,10 +120,12 @@
   Label* false_target() const { return false_target_; }
 
  private:
+  ArmCodeGenerator* owner_;
   AccessType access_;
   Reference* ref_;
   Label* true_target_;
   Label* false_target_;
+  CodeGenState* previous_;
 };
 
 
@@ -155,6 +140,9 @@
 
   MacroAssembler* masm()  { return masm_; }
 
+  CodeGenState* state() { return state_; }
+  void set_state(CodeGenState* state) { state_ = state; }
+
  private:
   // Assembler
   MacroAssembler* masm_;  // to generate code
@@ -181,7 +169,6 @@
   // The following are used by class Reference.
   void LoadReference(Reference* ref);
   void UnloadReference(Reference* ref);
-  friend class Reference;
 
   // State
   bool has_cc() const  { return cc_reg_ != al; }
@@ -197,21 +184,34 @@
     return ContextOperand(cp, Context::GLOBAL_INDEX);
   }
 
-  MemOperand ContextOperand(Register context, int index) const {
+  static MemOperand ContextOperand(Register context, int index) {
     return MemOperand(context, Context::SlotOffset(index));
   }
 
-  MemOperand ParameterOperand(int index) const {
+  static MemOperand ParameterOperand(Scope* scope, int index) {
     // index -2 corresponds to the activated closure, -1 corresponds
     // to the receiver
-    ASSERT(-2 <= index && index < scope_->num_parameters());
-    int offset = JavaScriptFrameConstants::kParam0Offset - index * kPointerSize;
-    return MemOperand(pp, offset);
+    ASSERT(-2 <= index && index < scope->num_parameters());
+    int offset = (1 + scope->num_parameters() - index) * kPointerSize;
+    return MemOperand(fp, offset);
   }
 
-  MemOperand FunctionOperand() const { return ParameterOperand(-2); }
+  MemOperand ParameterOperand(int index) const {
+    return ParameterOperand(scope_, index);
+  }
 
-  MemOperand SlotOperand(Slot* slot, Register tmp);
+  MemOperand FunctionOperand() const {
+    return MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset);
+  }
+
+  static MemOperand SlotOperand(MacroAssembler* masm,
+                                Scope* scope,
+                                Slot* slot,
+                                Register tmp);
+
+  MemOperand SlotOperand(Slot* slot, Register tmp) {
+    return SlotOperand(masm_, scope_, slot, tmp);
+  }
 
   void LoadCondition(Expression* x, CodeGenState::AccessType access,
                      Label* true_target, Label* false_target, bool force_cc);
@@ -227,22 +227,53 @@
   // through the context chain.
   void LoadTypeofExpression(Expression* x);
 
-  // References
-  void AccessReference(Reference* ref, CodeGenState::AccessType access);
 
-  void GetValue(Reference* ref)  { AccessReference(ref, CodeGenState::LOAD); }
-  void SetValue(Reference* ref)  { AccessReference(ref, CodeGenState::STORE); }
-  void InitConst(Reference* ref)  {
-    AccessReference(ref, CodeGenState::INIT_CONST);
+  // References
+
+  // Generate code to fetch the value of a reference.  The reference is
+  // expected to be on top of the expression stack.  It is left in place and
+  // its value is pushed on top of it.
+  void GetValue(Reference* ref) {
+    ASSERT(!has_cc());
+    ASSERT(!ref->is_illegal());
+    CodeGenState new_state(this, ref);
+    Visit(ref->expression());
   }
 
+  // Generate code to store a value in a reference.  The stored value is
+  // expected on top of the expression stack, with the reference immediately
+  // below it.  The expression stack is left unchanged.
+  void SetValue(Reference* ref) {
+    ASSERT(!has_cc());
+    ASSERT(!ref->is_illegal());
+    ref->expression()->GenerateStoreCode(masm_, scope_, ref, NOT_CONST_INIT);
+  }
+
+  // Generate code to store a value in a reference.  The stored value is
+  // expected on top of the expression stack, with the reference immediately
+  // below it.  The expression stack is left unchanged.
+  void InitConst(Reference* ref) {
+    ASSERT(!has_cc());
+    ASSERT(!ref->is_illegal());
+    ref->expression()->GenerateStoreCode(masm_, scope_, ref, CONST_INIT);
+  }
+
+  // Generate code to fetch a value from a property of a reference.  The
+  // reference is expected on top of the expression stack.  It is left in
+  // place and its value is pushed on top of it.
+  void GetReferenceProperty(Expression* key);
+
+  // Generate code to store a value in a property of a reference.  The
+  // stored value is expected on top of the expression stack, with the
+  // reference immediately below it.  The expression stack is left
+  // unchanged.
+  static void SetReferenceProperty(MacroAssembler* masm,
+                                   Reference* ref,
+                                   Expression* key);
+
+
   void ToBoolean(Label* true_target, Label* false_target);
 
-
-  // Access property from the reference (must be at the TOS).
-  void AccessReferenceProperty(Expression* key,
-                               CodeGenState::AccessType access);
-
   void GenericBinaryOperation(Token::Value op);
   void Comparison(Condition cc, bool strict = false);
 
@@ -271,19 +302,9 @@
   void RecordStatementPosition(Node* node);
 
   // Activation frames
-  void EnterJSFrame(int argc);  // preserves r1
-  void ExitJSFrame(ExitJSFlag flag = RETURN);  // preserves r0-r2
+  void EnterJSFrame();
+  void ExitJSFrame();
 
-  virtual void GenerateShiftDownAndTailCall(ZoneList<Expression*>* args);
-  virtual void GenerateSetThisFunction(ZoneList<Expression*>* args);
-  virtual void GenerateGetThisFunction(ZoneList<Expression*>* args);
-  virtual void GenerateSetThis(ZoneList<Expression*>* args);
-  virtual void GenerateGetArgumentsLength(ZoneList<Expression*>* args);
-  virtual void GenerateSetArgumentsLength(ZoneList<Expression*>* args);
-  virtual void GenerateTailCallWithArguments(ZoneList<Expression*>* args);
-  virtual void GenerateSetArgument(ZoneList<Expression*>* args);
-  virtual void GenerateSquashFrame(ZoneList<Expression*>* args);
-  virtual void GenerateExpandFrame(ZoneList<Expression*>* args);
   virtual void GenerateIsSmi(ZoneList<Expression*>* args);
   virtual void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
   virtual void GenerateIsArray(ZoneList<Expression*>* args);
@@ -297,9 +318,59 @@
   virtual void GenerateFastCharCodeAt(ZoneList<Expression*>* args);
 
   virtual void GenerateObjectEquals(ZoneList<Expression*>* args);
+
+  friend class Reference;
+  friend class Property;
+  friend class VariableProxy;
+  friend class Slot;
 };
 
 
+// -------------------------------------------------------------------------
+// CodeGenState implementation.
+
+CodeGenState::CodeGenState(ArmCodeGenerator* owner)
+    : owner_(owner),
+      access_(UNDEFINED),
+      ref_(NULL),
+      true_target_(NULL),
+      false_target_(NULL),
+      previous_(NULL) {
+  owner_->set_state(this);
+}
+
+
+CodeGenState::CodeGenState(ArmCodeGenerator* owner,
+                           AccessType access,
+                           Label* true_target,
+                           Label* false_target)
+    : owner_(owner),
+      access_(access),
+      ref_(NULL),
+      true_target_(true_target),
+      false_target_(false_target),
+      previous_(owner->state()) {
+  owner_->set_state(this);
+}
+
+
+CodeGenState::CodeGenState(ArmCodeGenerator* owner, Reference* ref)
+    : owner_(owner),
+      access_(LOAD),
+      ref_(ref),
+      true_target_(owner->state()->true_target_),
+      false_target_(owner->state()->false_target_),
+      previous_(owner->state()) {
+  owner_->set_state(this);
+}
+
+
+CodeGenState::~CodeGenState() {
+  ASSERT(owner_->state() == this);
+  owner_->set_state(previous_);
+}
+
+
 // -----------------------------------------------------------------------------
 // ArmCodeGenerator implementation
 
@@ -415,8 +486,7 @@
   ZoneList<Statement*>* body = fun->body();
 
   // Initialize state.
-  { CodeGenState state;
-    state_ = &state;
+  { CodeGenState state(this);
     scope_ = scope;
     cc_reg_ = al;
 
@@ -429,7 +499,7 @@
     // cp: callee's context
 
     { Comment cmnt(masm_, "[ enter JS frame");
-      EnterJSFrame(scope->num_parameters());
+      EnterJSFrame();
     }
     // tos: code slot
 #ifdef DEBUG
@@ -487,9 +557,7 @@
         Slot* slot = par->slot();
         if (slot != NULL && slot->type() == Slot::CONTEXT) {
           ASSERT(!scope->is_global_scope());  // no parameters in global scope
-          int parameter_offset =
-              JavaScriptFrameConstants::kParam0Offset - i * kPointerSize;
-          __ ldr(r1, MemOperand(pp, parameter_offset));
+          __ ldr(r1, ParameterOperand(i));
           // Loads r2 with context; used below in RecordWrite.
           __ str(r1, SlotOperand(slot, r2));
           // Load the offset into r3.
@@ -570,8 +638,6 @@
 #endif
       VisitStatements(body);
     }
-
-    state_ = NULL;
   }
 
   // exit
@@ -590,8 +656,13 @@
     __ CallRuntime(Runtime::kTraceExit, 1);
   }
 
+  // Tear down the frame which will restore the caller's frame pointer and the
+  // link register.
   ExitJSFrame();
 
+  __ add(sp, sp, Operand((scope_->num_parameters() + 1) * kPointerSize));
+  __ mov(pc, lr);
+
   // Code generation state must be reset.
   scope_ = NULL;
   ASSERT(!has_cc());
@@ -599,7 +670,10 @@
 }
 
 
-MemOperand ArmCodeGenerator::SlotOperand(Slot* slot, Register tmp) {
+MemOperand ArmCodeGenerator::SlotOperand(MacroAssembler* masm,
+                                         Scope* scope,
+                                         Slot* slot,
+                                         Register tmp) {
   // Currently, this assertion will fail if we try to assign to
   // a constant variable that is constant because it is read-only
   // (such as the variable referring to a named function expression).
@@ -612,11 +686,11 @@
   int index = slot->index();
   switch (slot->type()) {
     case Slot::PARAMETER:
-      return ParameterOperand(index);
+      return ParameterOperand(scope, index);
 
     case Slot::LOCAL: {
       ASSERT(0 <= index &&
-             index < scope_->num_stack_slots() &&
+             index < scope->num_stack_slots() &&
              index >= 0);
       int local_offset = JavaScriptFrameConstants::kLocal0Offset -
                          index * kPointerSize;
@@ -627,15 +701,15 @@
       // Follow the context chain if necessary.
       ASSERT(!tmp.is(cp));  // do not overwrite context register
       Register context = cp;
-      int chain_length = scope_->ContextChainLength(slot->var()->scope());
+      int chain_length = scope->ContextChainLength(slot->var()->scope());
       for (int i = chain_length; i-- > 0;) {
         // Load the closure.
         // (All contexts, even 'with' contexts, have a closure,
         // and it is the same for all contexts inside a function.
         // There is no need to go to the function context first.)
-        __ ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX));
+        masm->ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX));
         // Load the function context (which is the incoming, outer context).
-        __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset));
+        masm->ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset));
         context = tmp;
       }
       // We may have a 'with' context now. Get the function context.
@@ -645,7 +719,7 @@
       // cause the function context of a function context is itself. Before
       // deleting this mov we should try to create a counter-example first,
       // though...)
-      __ ldr(tmp, ContextOperand(context, Context::FCONTEXT_INDEX));
+      masm->ldr(tmp, ContextOperand(context, Context::FCONTEXT_INDEX));
       return ContextOperand(tmp, index);
     }
 
@@ -670,11 +744,9 @@
          access == CodeGenState::LOAD_TYPEOF_EXPR);
   ASSERT(!has_cc() && !is_referenced());
 
-  CodeGenState* old_state = state_;
-  CodeGenState new_state(access, NULL, true_target, false_target);
-  state_ = &new_state;
-  Visit(x);
-  state_ = old_state;
+  { CodeGenState new_state(this, access, true_target, false_target);
+    Visit(x);
+  }
   if (force_cc && !has_cc()) {
     // Convert the TOS value to a boolean in the condition code register.
     ToBoolean(true_target, false_target);
@@ -822,15 +894,117 @@
 }
 
 
-void ArmCodeGenerator::AccessReference(Reference* ref,
-                                       CodeGenState::AccessType access) {
-  ASSERT(!has_cc());
-  ASSERT(ref->type() != Reference::ILLEGAL);
-  CodeGenState* old_state = state_;
-  CodeGenState new_state(access, ref, true_target(), false_target());
-  state_ = &new_state;
-  Visit(ref->expression());
-  state_ = old_state;
+void Property::GenerateStoreCode(MacroAssembler* masm,
+                                 Scope* scope,
+                                 Reference* ref,
+                                 InitState init_state) {
+  Comment cmnt(masm, "[ Store to Property");
+  masm->RecordPosition(position());
+  ArmCodeGenerator::SetReferenceProperty(masm, ref, key());
+}
+
+
+void VariableProxy::GenerateStoreCode(MacroAssembler* masm,
+                                      Scope* scope,
+                                      Reference* ref,
+                                      InitState init_state) {
+  Comment cmnt(masm, "[ Store to VariableProxy");
+  Variable* node = var();
+
+  Expression* expr = node->rewrite();
+  if (expr != NULL) {
+    expr->GenerateStoreCode(masm, scope, ref, init_state);
+  } else {
+    ASSERT(node->is_global());
+    if (node->AsProperty() != NULL) {
+      masm->RecordPosition(node->AsProperty()->position());
+    }
+    ArmCodeGenerator::SetReferenceProperty(masm, ref,
+                                           new Literal(node->name()));
+  }
+}
+
+
+void Slot::GenerateStoreCode(MacroAssembler* masm,
+                             Scope* scope,
+                             Reference* ref,
+                             InitState init_state) {
+  Comment cmnt(masm, "[ Store to Slot");
+
+  if (type() == Slot::LOOKUP) {
+    ASSERT(var()->mode() == Variable::DYNAMIC);
+
+    // For now, just do a runtime call.
+    masm->push(cp);
+    masm->mov(r0, Operand(var()->name()));
+    masm->push(r0);
+
+    if (init_state == CONST_INIT) {
+      // Same as the case for a normal store, but ignores attribute
+      // (e.g. READ_ONLY) of context slot so that we can initialize const
+      // properties (introduced via eval("const foo = (some expr);")). Also,
+      // uses the current function context instead of the top context.
+      //
+      // Note that we must declare the foo upon entry of eval(), via a
+      // context slot declaration, but we cannot initialize it at the same
+      // time, because the const declaration may be at the end of the eval
+      // code (sigh...) and the const variable may have been used before
+      // (where its value is 'undefined'). Thus, we can only do the
+      // initialization when we actually encounter the expression and when
+      // the expression operands are defined and valid, and thus we need the
+      // split into 2 operations: declaration of the context slot followed
+      // by initialization.
+      masm->CallRuntime(Runtime::kInitializeConstContextSlot, 3);
+    } else {
+      masm->CallRuntime(Runtime::kStoreContextSlot, 3);
+    }
+    // Storing a variable must keep the (new) value on the expression
+    // stack. This is necessary for compiling assignment expressions.
+    masm->push(r0);
+
+  } else {
+    ASSERT(var()->mode() != Variable::DYNAMIC);
+
+    Label exit;
+    if (init_state == CONST_INIT) {
+      ASSERT(var()->mode() == Variable::CONST);
+      // Only the first const initialization must be executed (the slot
+      // still contains 'the hole' value). When the assignment is executed,
+      // the code is identical to a normal store (see below).
+      Comment cmnt(masm, "[ Init const");
+      masm->ldr(r2, ArmCodeGenerator::SlotOperand(masm, scope, this, r2));
+      masm->cmp(r2, Operand(Factory::the_hole_value()));
+      masm->b(ne, &exit);
+    }
+
+    // We must execute the store.
+    // r2 may be loaded with context; used below in RecordWrite.
+    // Storing a variable must keep the (new) value on the stack. This is
+    // necessary for compiling assignment expressions.
+    //
+    // Note: We will reach here even with var()->mode() == Variable::CONST
+    // because of const declarations which will initialize consts to 'the
+    // hole' value and by doing so, end up calling this code.  r2 may be
+    // loaded with context; used below in RecordWrite.
+    masm->pop(r0);
+    masm->str(r0, ArmCodeGenerator::SlotOperand(masm, scope, this, r2));
+    masm->push(r0);
+
+    if (type() == Slot::CONTEXT) {
+      // Skip write barrier if the written value is a smi.
+      masm->tst(r0, Operand(kSmiTagMask));
+      masm->b(eq, &exit);
+      // r2 is loaded with context when calling SlotOperand above.
+      int offset = FixedArray::kHeaderSize + index() * kPointerSize;
+      masm->mov(r3, Operand(offset));
+      masm->RecordWrite(r2, r3, r1);
+    }
+    // If we definitely did not jump over the assignment, we do not need to
+    // bind the exit label.  Doing so can defeat peephole optimization.
+    if (init_state == CONST_INIT || type() == Slot::CONTEXT) {
+      masm->bind(&exit);
+    }
+  }
 }
 
 
@@ -1125,7 +1299,7 @@
       __ push(r1);
       __ push(r0);
       __ mov(r0, Operand(1));  // set number of arguments
-      __ InvokeBuiltin("ADD", 1, JUMP_JS);
+      __ InvokeBuiltin(Builtins::ADD, JUMP_JS);
       // done
       __ bind(&exit);
       break;
@@ -1148,7 +1322,7 @@
       __ push(r1);
       __ push(r0);
       __ mov(r0, Operand(1));  // set number of arguments
-      __ InvokeBuiltin("SUB", 1, JUMP_JS);
+      __ InvokeBuiltin(Builtins::SUB, JUMP_JS);
       // done
       __ bind(&exit);
       break;
@@ -1178,7 +1352,7 @@
       __ push(r1);
       __ push(r0);
       __ mov(r0, Operand(1));  // set number of arguments
-      __ InvokeBuiltin("MUL", 1, JUMP_JS);
+      __ InvokeBuiltin(Builtins::MUL, JUMP_JS);
       // done
       __ bind(&exit);
       break;
@@ -1205,10 +1379,17 @@
       __ push(r0);
       __ mov(r0, Operand(1));  // 1 argument (not counting receiver).
       switch (op_) {
-        case Token::BIT_OR:  __ InvokeBuiltin("BIT_OR",  1, JUMP_JS); break;
-        case Token::BIT_AND: __ InvokeBuiltin("BIT_AND", 1, JUMP_JS); break;
-        case Token::BIT_XOR: __ InvokeBuiltin("BIT_XOR", 1, JUMP_JS); break;
-        default: UNREACHABLE();
+        case Token::BIT_OR:
+          __ InvokeBuiltin(Builtins::BIT_OR, JUMP_JS);
+          break;
+        case Token::BIT_AND:
+          __ InvokeBuiltin(Builtins::BIT_AND, JUMP_JS);
+          break;
+        case Token::BIT_XOR:
+          __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_JS);
+          break;
+        default:
+          UNREACHABLE();
       }
       __ bind(&exit);
       break;
@@ -1266,9 +1447,9 @@
       __ push(r0);
       __ mov(r0, Operand(1));  // 1 argument (not counting receiver).
       switch (op_) {
-        case Token::SAR: __ InvokeBuiltin("SAR", 1, JUMP_JS); break;
-        case Token::SHR: __ InvokeBuiltin("SHR", 1, JUMP_JS); break;
-        case Token::SHL: __ InvokeBuiltin("SHL", 1, JUMP_JS); break;
+        case Token::SAR: __ InvokeBuiltin(Builtins::SAR, JUMP_JS); break;
+        case Token::SHR: __ InvokeBuiltin(Builtins::SHR, JUMP_JS); break;
+        case Token::SHL: __ InvokeBuiltin(Builtins::SHL, JUMP_JS); break;
         default: UNREACHABLE();
       }
       __ bind(&exit);
@@ -1324,7 +1505,7 @@
   __ bind(&slow);
   __ push(r0);
   __ mov(r0, Operand(0));  // set number of arguments
-  __ InvokeBuiltin("UNARY_MINUS", 0, JUMP_JS);
+  __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_JS);
 
   __ bind(&done);
   masm->StubReturn(1);
@@ -1360,45 +1541,15 @@
   __ push(r0);
   __ mov(r0, Operand(0));  // set number of arguments
   switch (kind_) {
-    case ToNumber: __ InvokeBuiltin("TO_NUMBER", 0, JUMP_JS); break;
-    case Inc:      __ InvokeBuiltin("INC", 0, JUMP_JS);       break;
-    case Dec:      __ InvokeBuiltin("DEC", 0, JUMP_JS);       break;
+    case ToNumber: __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_JS); break;
+    case Inc:      __ InvokeBuiltin(Builtins::INC, JUMP_JS);       break;
+    case Dec:      __ InvokeBuiltin(Builtins::DEC, JUMP_JS);       break;
     default: UNREACHABLE();
   }
   masm->StubReturn(argc_);
 }
 
 
-class JSExitStub : public CodeStub {
- public:
-  enum Kind { Inc, Dec, ToNumber };
-
-  explicit JSExitStub(ExitJSFlag flag) : flag_(flag) { }
-
- private:
-  ExitJSFlag flag_;
-
-  Major MajorKey() { return JSExit; }
-  int MinorKey() { return static_cast<int>(flag_); }
-  void Generate(MacroAssembler* masm);
-
-  const char* GetName() { return "JSExitStub"; }
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("JSExitStub flag %d)\n", static_cast<int>(flag_));
-  }
-#endif
-};
-
-
-void JSExitStub::Generate(MacroAssembler* masm) {
-  __ ExitJSFrame(flag_);
-  masm->StubReturn(1);
-}
-
-
-
 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
   // r0 holds exception
   ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize);  // adjust this code
@@ -1545,7 +1696,7 @@
   __ mov(r3, Operand(Top::context_address()));
   __ ldr(cp, MemOperand(r3));
   __ mov(sp, Operand(fp));  // respect ABI stack constraint
-  __ ldm(ia, sp, pp.bit() | fp.bit() | sp.bit() | pc.bit());
+  __ ldm(ia, sp, fp.bit() | sp.bit() | pc.bit());
 
   // check if we should retry or throw exception
   Label retry;
@@ -1599,13 +1750,13 @@
   // ip = sp + kPointerSize*args_len;
   __ add(ip, sp, Operand(r0, LSL, kPointerSizeLog2));
 
-  // all JS callee-saved are saved and traversed by GC; push in reverse order:
-  // JS callee-saved, caller_pp, caller_fp, sp_on_exit (ip==pp), caller_pc
-  __ stm(db_w, sp, pp.bit() | fp.bit() | ip.bit() | lr.bit());
+  // push in reverse order:
+  // caller_fp, sp_on_exit, caller_pc
+  __ stm(db_w, sp, fp.bit() | ip.bit() | lr.bit());
   __ mov(fp, Operand(sp));  // setup new frame pointer
 
   // Store the current context in top.
-  __ mov(ip, Operand(Top::context_address()));
+  __ mov(ip, Operand(ExternalReference(Top::k_context_address)));
   __ str(cp, MemOperand(ip));
 
   // remember top frame
@@ -1682,33 +1833,40 @@
   // Called from C, so do not pop argc and args on exit (preserve sp)
   // No need to save register-passed args
   // Save callee-saved registers (incl. cp, pp, and fp), sp, and lr
-  __ mov(ip, Operand(sp));
-  __ stm(db_w, sp, kCalleeSaved | ip.bit() | lr.bit());
-
-  // Setup frame pointer
-  __ mov(fp, Operand(sp));
-
-  // Add constructor mark.
-  __ mov(ip, Operand(is_construct ? 1 : 0));
-  __ push(ip);
-
-  // Move arguments into registers expected by Builtins::JSEntryTrampoline
-  // preserve r0-r3, set r4, r5-r7 may be clobbered
+  __ stm(db_w, sp, kCalleeSaved | lr.bit());
 
   // Get address of argv, see stm above.
-  __ add(r4, sp, Operand((kNumCalleeSaved + 3)*kPointerSize));
+  // r0: code entry
+  // r1: function
+  // r2: receiver
+  // r3: argc
+  __ add(r4, sp, Operand((kNumCalleeSaved + 1)*kPointerSize));
   __ ldr(r4, MemOperand(r4));  // argv
 
-  // Save copies of the top frame descriptors on the stack.
-  __ mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
-  __ ldr(r6, MemOperand(ip));
-  __ stm(db_w, sp, r6.bit());
+  // Push a frame with special values setup to mark it as an entry frame.
+  // r0: code entry
+  // r1: function
+  // r2: receiver
+  // r3: argc
+  // r4: argv
+  int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
+  __ mov(r8, Operand(-1));  // Push a bad frame pointer to fail if it is used.
+  __ mov(r7, Operand(~ArgumentsAdaptorFrame::SENTINEL));
+  __ mov(r6, Operand(Smi::FromInt(marker)));
+  __ mov(r5, Operand(ExternalReference(Top::k_c_entry_fp_address)));
+  __ ldr(r5, MemOperand(r5));
+  __ stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | r8.bit());
+
+  // Setup frame pointer for the frame to be pushed.
+  __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
 
   // Call a faked try-block that does the invoke.
   __ bl(&invoke);
 
   // Caught exception: Store result (exception) in the pending
   // exception field in the JSEnv and return a failure sentinel.
+  // Coming in here the fp will be invalid because the PushTryHandler below
+  // sets it to 0 to signal the existence of the JSEntry frame.
   __ mov(ip, Operand(Top::pending_exception_address()));
   __ str(r0, MemOperand(ip));
   __ mov(r0, Operand(Handle<Failure>(Failure::Exception())));
@@ -1716,7 +1874,7 @@
 
   // Invoke: Link this frame into the handler chain.
   __ bind(&invoke);
-  // Must preserve r0-r3, r5-r7 are available.
+  // Must preserve r0-r4, r5-r7 are available.
   __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER);
   // If an exception not caught by another handler occurs, this handler returns
   // control to the code after the bl(&invoke) above, which restores all
@@ -1764,18 +1922,18 @@
 
   __ bind(&exit);  // r0 holds result
   // Restore the top frame descriptors from the stack.
-  __ ldm(ia_w, sp, r3.bit());
+  __ pop(r3);
   __ mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
   __ str(r3, MemOperand(ip));
 
-  // Remove constructor mark.
-  __ pop();
+  // Reset the stack to the callee saved registers.
+  __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
 
-  // Restore callee-saved registers, sp, and return.
+  // Restore callee-saved registers and return.
 #ifdef DEBUG
   if (FLAG_debug_code) __ mov(lr, Operand(pc));
 #endif
-  __ ldm(ia, sp, kCalleeSaved | sp.bit() | pc.bit());
+  __ ldm(ia_w, sp, kCalleeSaved | pc.bit());
 }
 
 
@@ -1802,31 +1960,82 @@
 
 
 void ArgumentsAccessStub::Generate(MacroAssembler* masm) {
-  if (is_length_) {
-    __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kArgsLengthOffset));
-    __ mov(r0, Operand(r0, LSL, kSmiTagSize));
-    __ Ret();
-  } else {
-    // Check that the key is a smi.
-    Label slow;
-    __ tst(r0, Operand(kSmiTagMask));
+  // ----------- S t a t e -------------
+  //  -- r0: formal number of parameters for the calling function
+  //  -- r1: key (if value access)
+  //  -- lr: return address
+  // -----------------------------------
+
+  // Check that the key is a smi for non-length accesses.
+  Label slow;
+  if (!is_length_) {
+    __ tst(r1, Operand(kSmiTagMask));
     __ b(ne, &slow);
+  }
 
-    // Get the actual number of arguments passed and do bounds
-    // check. Use unsigned comparison to get negative check for free.
-    __ ldr(r1, MemOperand(fp, JavaScriptFrameConstants::kArgsLengthOffset));
-    __ cmp(r0, Operand(r1, LSL, kSmiTagSize));
-    __ b(hs, &slow);
+  // Check if the calling frame is an arguments adaptor frame.
+  // r0: formal number of parameters
+  // r1: key (if access)
+  Label adaptor;
+  __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
+  __ cmp(r3, Operand(ArgumentsAdaptorFrame::SENTINEL));
+  __ b(eq, &adaptor);
 
-    // Load the argument directly from the stack and return.
-    __ sub(r1, pp, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
-    __ ldr(r0, MemOperand(r1, JavaScriptFrameConstants::kParam0Offset));
-    __ Ret();
+  static const int kParamDisplacement =
+      StandardFrameConstants::kCallerSPOffset - kPointerSize;
 
-    // Slow-case: Handle non-smi or out-of-bounds access to arguments
-    // by calling the runtime system.
+  if (is_length_) {
+    // Nothing to do: the formal length of parameters has been passed in r0
+    // by the calling function.
+  } else {
+    // Check index against formal parameter count. Use unsigned comparison to
+    // get the negative check for free.
+    // r0: formal number of parameters
+    // r1: index
+    __ cmp(r1, r0);
+    __ b(cs, &slow);
+
+    // Read the argument from the current frame.
+    __ sub(r3, r0, r1);
+    __ add(r3, fp, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize));
+    __ ldr(r0, MemOperand(r3, kParamDisplacement));
+  }
+
+  // Return to the calling function.
+  __ mov(pc, lr);
+
+  // An arguments adaptor frame is present. Find the length or the actual
+  // argument in the calling frame.
+  // r0: formal number of parameters
+  // r1: key
+  // r2: adaptor frame pointer
+  __ bind(&adaptor);
+  // Read the arguments length from the adaptor frame. This is the result if
+  // only accessing the length, otherwise it is used in accessing the value
+  __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
+
+  if (!is_length_) {
+    // Check index against actual arguments count. Use unsigned comparison to
+    // get the negative check for free.
+    // r0: actual number of parameter
+    // r1: index
+    // r2: adaptor frame point
+    __ cmp(r1, r0);
+    __ b(cs, &slow);
+
+    // Read the argument from the adaptor frame.
+    __ sub(r3, r0, r1);
+    __ add(r3, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize));
+    __ ldr(r0, MemOperand(r3, kParamDisplacement));
+  }
+
+  // Return to the calling function.
+  __ mov(pc, lr);
+
+  if (!is_length_) {
     __ bind(&slow);
-    __ push(r0);
+    __ push(r1);
     __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
   }
 }
@@ -1836,42 +2045,29 @@
 #define __  masm_->
 
 
-void ArmCodeGenerator::AccessReferenceProperty(
-    Expression* key,
-    CodeGenState::AccessType access) {
+void ArmCodeGenerator::GetReferenceProperty(Expression* key) {
+  ASSERT(!ref()->is_illegal());
   Reference::Type type = ref()->type();
-  ASSERT(type != Reference::ILLEGAL);
 
-  // TODO(1241834): Make sure that this is sufficient. If there is a chance
-  // that reference errors can be thrown below, we must distinguish
-  // between the 2 kinds of loads (typeof expression loads must not
-  // throw a reference error).
-  bool is_load = (access == CodeGenState::LOAD ||
-                  access == CodeGenState::LOAD_TYPEOF_EXPR);
-
+  // TODO(1241834): Make sure that this it is safe to ignore the distinction
+  // between access types LOAD and LOAD_TYPEOF_EXPR. If there is a chance
+  // that reference errors can be thrown below, we must distinguish between
+  // the two kinds of loads (typeof expression loads must not throw a
+  // reference error).
   if (type == Reference::NAMED) {
     // Compute the name of the property.
     Literal* literal = key->AsLiteral();
     Handle<String> name(String::cast(*literal->handle()));
 
     // Call the appropriate IC code.
-    if (is_load) {
-      // Setup the name register.
-      __ mov(r2, Operand(name));
-      Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
-      Variable* var = ref()->expression()->AsVariableProxy()->AsVariable();
-      if (var != NULL) {
-        ASSERT(var->is_global());
-        __ Call(ic, code_target_context);
-      } else {
-        __ Call(ic, code_target);
-      }
-
+    // Setup the name register.
+    __ mov(r2, Operand(name));
+    Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
+    Variable* var = ref()->expression()->AsVariableProxy()->AsVariable();
+    if (var != NULL) {
+      ASSERT(var->is_global());
+      __ Call(ic, code_target_context);
     } else {
-      __ pop(r0);  // value
-      // Setup the name register.
-      __ mov(r2, Operand(name));
-      Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
       __ Call(ic, code_target);
     }
 
@@ -1879,21 +2075,44 @@
     // Access keyed property.
     ASSERT(type == Reference::KEYED);
 
-    if (is_load) {
-      // TODO(1224671): Implement inline caching for keyed loads as on ia32.
-      GetPropertyStub stub;
-      __ CallStub(&stub);
-
-    } else {
-      __ pop(r0);  // value
-      SetPropertyStub stub;
-      __ CallStub(&stub);
-    }
+    // TODO(1224671): Implement inline caching for keyed loads as on ia32.
+    GetPropertyStub stub;
+    __ CallStub(&stub);
   }
   __ push(r0);
 }
 
 
+void ArmCodeGenerator::SetReferenceProperty(MacroAssembler* masm,
+                                            Reference* ref,
+                                            Expression* key) {
+  ASSERT(!ref->is_illegal());
+  Reference::Type type = ref->type();
+
+  if (type == Reference::NAMED) {
+    // Compute the name of the property.
+    Literal* literal = key->AsLiteral();
+    Handle<String> name(String::cast(*literal->handle()));
+
+    // Call the appropriate IC code.
+    masm->pop(r0);  // value
+    // Setup the name register.
+    masm->mov(r2, Operand(name));
+    Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+    masm->Call(ic, code_target);
+
+  } else {
+    // Access keyed property.
+    ASSERT(type == Reference::KEYED);
+
+    masm->pop(r0);  // value
+    SetPropertyStub stub;
+    masm->CallStub(&stub);
+  }
+  masm->push(r0);
+}
+
+
 void ArmCodeGenerator::GenericBinaryOperation(Token::Value op) {
   // sp[0] : y
   // sp[1] : x
@@ -1919,13 +2138,13 @@
 
     case Token::DIV: {
       __ mov(r0, Operand(1));
-      __ InvokeBuiltin("DIV", 1, CALL_JS);
+      __ InvokeBuiltin(Builtins::DIV, CALL_JS);
       break;
     }
 
     case Token::MOD: {
       __ mov(r0, Operand(1));
-      __ InvokeBuiltin("MOD", 1, CALL_JS);
+      __ InvokeBuiltin(Builtins::MOD, CALL_JS);
       break;
     }
 
@@ -2180,13 +2399,13 @@
   __ push(r1);
 
   // Figure out which native to call and setup the arguments.
-  const char* native;
+  Builtins::JavaScript native;
   int argc;
   if (cc == eq) {
-    native = strict ? "STRICT_EQUALS" : "EQUALS";
+    native = strict ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
     argc = 1;
   } else {
-    native = "COMPARE";
+    native = Builtins::COMPARE;
     int ncr;  // NaN compare result
     if (cc == lt || cc == le) {
       ncr = GREATER;
@@ -2203,7 +2422,7 @@
   // tagged as a small integer.
   __ push(r0);
   __ mov(r0, Operand(argc));
-  __ InvokeBuiltin(native, argc, CALL_JS);
+  __ InvokeBuiltin(native, CALL_JS);
   __ cmp(r0, Operand(0));
   __ b(&exit);
 
@@ -2260,7 +2479,7 @@
   // Slow-case: Non-function called.
   masm->bind(&slow);
   masm->mov(r0, Operand(argc_));  // Setup the number of arguments.
-  masm->InvokeBuiltin("CALL_NON_FUNCTION", argc_, JUMP_JS);
+  masm->InvokeBuiltin(Builtins::CALL_NON_FUNCTION, JUMP_JS);
 }
 
 
@@ -2542,19 +2761,14 @@
     Comment cmnt(masm_, "[ case clause");
 
     if (clause->is_default()) {
+      // Continue matching cases. The program will execute the default case's
+      // statements if it does not match any of the cases.
+      __ b(&next);
+
       // Bind the default case label, so we can branch to it when we
       // have compared against all other cases.
       ASSERT(default_case.is_unused());  // at most one default clause
-
-      // If the default case is the first (but not only) case, we have
-      // to jump past it for now. Once we're done with the remaining
-      // clauses, we'll branch back here. If it isn't the first case,
-      // we jump past it by avoiding to chain it into the next chain.
-      if (length > 1) {
-        if (i == 0) __ b(&next);
-        __ bind(&default_case);
-      }
-
+      __ bind(&default_case);
     } else {
       __ bind(&next);
       next.Unuse();
@@ -2563,11 +2777,16 @@
       Load(clause->label());
       Comparison(eq, true);
       Branch(false, &next);
-      // Entering the case statement -> remove the switch value from the stack
-      __ pop(r0);
     }
 
+    // Entering the case statement for the first time. Remove the switch value
+    // from the stack.
+    __ pop(r0);
+
     // Generate code for the body.
+    // This is also the target for the fall through from the previous case's
+    // statements which has to skip over the matching code and the popping of
+    // the switch value.
     __ bind(&fall_through);
     fall_through.Unuse();
     VisitStatements(clause->statements());
@@ -2575,10 +2794,14 @@
   }
 
   __ bind(&next);
-  // Reached the end of the case statements -> remove the switch value
-  // from the stack.
-  __ pop(r0);  // __ Pop(no_reg)
-  if (default_case.is_bound()) __ b(&default_case);
+  // Reached the end of the case statements without matching any of the cases.
+  if (default_case.is_bound()) {
+    // A default case exists -> execute its statements.
+    __ b(&default_case);
+  } else {
+    // Remove the switch value from the stack.
+    __ pop(r0);
+  }
 
   __ bind(&fall_through);
   __ bind(node->break_target());
@@ -2700,7 +2923,7 @@
   __ bind(&primitive);
   __ push(r0);
   __ mov(r0, Operand(0));
-  __ InvokeBuiltin("TO_OBJECT", 0, CALL_JS);
+  __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
 
 
   __ bind(&jsobject);
@@ -2794,7 +3017,7 @@
   __ push(r0);
   __ push(r3);  // push entry
   __ mov(r0, Operand(1));
-  __ InvokeBuiltin("FILTER_KEY", 1, CALL_JS);
+  __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_JS);
   __ mov(r3, Operand(r0));
 
   // If the property has been removed while iterating, we just skip it.
@@ -3116,6 +3339,7 @@
 
 
 void ArmCodeGenerator::VisitSlot(Slot* node) {
+  ASSERT(access() != CodeGenState::UNDEFINED);
   Comment cmnt(masm_, "[ Slot");
 
   if (node->type() == Slot::LOOKUP) {
@@ -3126,161 +3350,54 @@
     __ mov(r0, Operand(node->var()->name()));
     __ push(r0);
 
-    switch (access()) {
-      case CodeGenState::UNDEFINED:
-        UNREACHABLE();
-        break;
-
-      case CodeGenState::LOAD:
-        __ CallRuntime(Runtime::kLoadContextSlot, 2);
-        __ push(r0);
-        break;
-
-      case CodeGenState::LOAD_TYPEOF_EXPR:
-        __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
-        __ push(r0);
-        break;
-
-      case CodeGenState::STORE:
-        // Storing a variable must keep the (new) value on the stack. This
-        // is necessary for compiling assignment expressions.
-        __ CallRuntime(Runtime::kStoreContextSlot, 3);
-        __ push(r0);
-        // result (TOS) is the value that was stored
-        break;
-
-      case CodeGenState::INIT_CONST:
-        // Same as STORE but ignores attribute (e.g. READ_ONLY) of
-        // context slot so that we can initialize const properties
-        // (introduced via eval("const foo = (some expr);")). Also,
-        // uses the current function context instead of the top
-        // context.
-        //
-        // Note that we must declare the foo upon entry of eval(),
-        // via a context slot declaration, but we cannot initialize
-        // it at the same time, because the const declaration may
-        // be at the end of the eval code (sigh...) and the const
-        // variable may have been used before (where its value is
-        // 'undefined'). Thus, we can only do the initialization
-        // when we actually encounter the expression and when the
-        // expression operands are defined and valid, and thus we
-        // need the split into 2 operations: declaration of the
-        // context slot followed by initialization.
-        __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
-        __ push(r0);
-        break;
+    if (access() == CodeGenState::LOAD) {
+      __ CallRuntime(Runtime::kLoadContextSlot, 2);
+    } else {
+      ASSERT(access() == CodeGenState::LOAD_TYPEOF_EXPR);
+      __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
     }
+    __ push(r0);
 
   } else {
-    // Note: We would like to keep the assert below, but it fires because
-    // of some nasty code in LoadTypeofExpression() which should be removed...
+    // Note: We would like to keep the assert below, but it fires because of
+    // some nasty code in LoadTypeofExpression() which should be removed...
     // ASSERT(node->var()->mode() != Variable::DYNAMIC);
 
-    switch (access()) {
-      case CodeGenState::UNDEFINED:
-        UNREACHABLE();
-        break;
-
-      case CodeGenState::LOAD:  // fall through
-      case CodeGenState::LOAD_TYPEOF_EXPR:
-        // Special handling for locals allocated in registers.
-        __ ldr(r0, SlotOperand(node, r2));
-        __ push(r0);
-        if (node->var()->mode() == Variable::CONST) {
-          // Const slots may contain 'the hole' value (the constant hasn't
-          // been initialized yet) which needs to be converted into the
-          // 'undefined' value.
-          Comment cmnt(masm_, "[ Unhole const");
-          __ pop(r0);
-          __ cmp(r0, Operand(Factory::the_hole_value()));
-          __ mov(r0, Operand(Factory::undefined_value()), LeaveCC, eq);
-          __ push(r0);
-        }
-        break;
-
-      case CodeGenState::INIT_CONST: {
-        ASSERT(node->var()->mode() == Variable::CONST);
-        // Only the first const initialization must be executed (the slot
-        // still contains 'the hole' value). When the assignment is executed,
-        // the code is identical to a normal store (see below).
-        { Comment cmnt(masm_, "[ Init const");
-          Label L;
-          __ ldr(r2, SlotOperand(node, r2));
-          __ cmp(r2, Operand(Factory::the_hole_value()));
-          __ b(ne, &L);
-          // We must execute the store.
-          // r2 may be loaded with context; used below in RecordWrite.
-          __ ldr(r0, MemOperand(sp, 0));
-          __ str(r0, SlotOperand(node, r2));
-          if (node->type() == Slot::CONTEXT) {
-            // Skip write barrier if the written value is a smi.
-            Label exit;
-            __ tst(r0, Operand(kSmiTagMask));
-            __ b(eq, &exit);
-            // r2 is loaded with context when calling SlotOperand above.
-            int offset = FixedArray::kHeaderSize + node->index() * kPointerSize;
-            __ mov(r3, Operand(offset));
-            __ RecordWrite(r2, r3, r1);
-            __ bind(&exit);
-          }
-          __ bind(&L);
-        }
-        break;
-      }
-
-      case CodeGenState::STORE: {
-        // Storing a variable must keep the (new) value on the stack. This
-        // is necessary for compiling assignment expressions.
-        // Special handling for locals allocated in registers.
-        //
-        // Note: We will reach here even with node->var()->mode() ==
-        // Variable::CONST because of const declarations which will
-        // initialize consts to 'the hole' value and by doing so, end
-        // up calling this code.
-        // r2 may be loaded with context; used below in RecordWrite.
-        __ pop(r0);
-        __ str(r0, SlotOperand(node, r2));
-        __ push(r0);
-        if (node->type() == Slot::CONTEXT) {
-          // Skip write barrier if the written value is a smi.
-          Label exit;
-          __ tst(r0, Operand(kSmiTagMask));
-          __ b(eq, &exit);
-          // r2 is loaded with context when calling SlotOperand above.
-          int offset = FixedArray::kHeaderSize + node->index() * kPointerSize;
-          __ mov(r3, Operand(offset));
-          __ RecordWrite(r2, r3, r1);
-          __ bind(&exit);
-        }
-        break;
-      }
+    // Special handling for locals allocated in registers.
+    __ ldr(r0, SlotOperand(node, r2));
+    __ push(r0);
+    if (node->var()->mode() == Variable::CONST) {
+      // Const slots may contain 'the hole' value (the constant hasn't been
+      // initialized yet) which needs to be converted into the 'undefined'
+      // value.
+      Comment cmnt(masm_, "[ Unhole const");
+      __ pop(r0);
+      __ cmp(r0, Operand(Factory::the_hole_value()));
+      __ mov(r0, Operand(Factory::undefined_value()), LeaveCC, eq);
+      __ push(r0);
     }
   }
 }
 
 
-void ArmCodeGenerator::VisitVariableProxy(VariableProxy* proxy_node) {
+void ArmCodeGenerator::VisitVariableProxy(VariableProxy* node) {
   Comment cmnt(masm_, "[ VariableProxy");
-  Variable* node = proxy_node->var();
+  Variable* var_node = node->var();
 
-  Expression* x = node->rewrite();
-  if (x != NULL) {
-    Visit(x);
-    return;
-  }
-
-  ASSERT(node->is_global());
-  if (is_referenced()) {
-    if (node->AsProperty() != NULL) {
-      __ RecordPosition(node->AsProperty()->position());
-    }
-    AccessReferenceProperty(new Literal(node->name()), access());
-
+  Expression* expr = var_node->rewrite();
+  if (expr != NULL) {
+    Visit(expr);
   } else {
-    // All stores are through references.
-    ASSERT(access() != CodeGenState::STORE);
-    Reference property(this, proxy_node);
-    GetValue(&property);
+    ASSERT(var_node->is_global());
+    if (is_referenced()) {
+      if (var_node->AsProperty() != NULL) {
+        __ RecordPosition(var_node->AsProperty()->position());
+      }
+      GetReferenceProperty(new Literal(var_node->name()));
+    } else {
+      Reference property(this, node);
+      GetValue(&property);
+    }
   }
 }
 
@@ -3298,7 +3415,7 @@
   // Retrieve the literal array and check the allocated entry.
 
   // Load the function of this activation.
-  __ ldr(r1, MemOperand(pp, 0));
+  __ ldr(r1, FunctionOperand());
 
   // Load the literals array of the function.
   __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
@@ -3371,7 +3488,7 @@
   // Retrieve the literal array and check the allocated entry.
 
   // Load the function of this activation.
-  __ ldr(r1, MemOperand(pp, 0));
+  __ ldr(r1, FunctionOperand());
 
   // Load the literals array of the function.
   __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
@@ -3442,12 +3559,9 @@
   // Call runtime to create the array literal.
   __ mov(r0, Operand(node->literals()));
   __ push(r0);
-  // TODO(1332579): The second argument to CreateArrayLiteral is
-  // supposed to be the literals array of the function of this frame.
-  // Until the new ARM calling convention is in place, that function
-  // is not always available.  Therefore, on ARM we pass in the hole
-  // until the new calling convention is in place.
-  __ mov(r0, Operand(Factory::the_hole_value()));
+  // Load the function of this frame.
+  __ ldr(r0, FunctionOperand());
+  __ ldr(r0, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
   __ push(r0);
   __ CallRuntime(Runtime::kCreateArrayLiteral, 2);
 
@@ -3541,13 +3655,11 @@
 
 void ArmCodeGenerator::VisitProperty(Property* node) {
   Comment cmnt(masm_, "[ Property");
+
   if (is_referenced()) {
     __ RecordPosition(node->position());
-    AccessReferenceProperty(node->key(), access());
-
+    GetReferenceProperty(node->key());
   } else {
-    // All stores are through references.
-    ASSERT(access() != CodeGenState::STORE);
     Reference property(this, node);
     __ RecordPosition(node->position());
     GetValue(&property);
@@ -3702,6 +3814,9 @@
   // r0: the number of arguments.
   __ mov(r0, Operand(args->length()));
 
+  // Load the function into r1 as per calling convention.
+  __ ldr(r1, MemOperand(sp, (args->length() + 1) * kPointerSize));
+
   // Call the construct call builtin that handles allocation and
   // constructor invocation.
   __ RecordPosition(position);
@@ -3713,48 +3828,6 @@
 }
 
 
-void ArmCodeGenerator::GenerateSetThisFunction(ZoneList<Expression*>* args) {
-  ASSERT(args->length() == 1);
-  Load(args->at(0));
-  __ ldr(r0, MemOperand(sp, 0));
-  __ str(r0, MemOperand(pp, JavaScriptFrameConstants::kFunctionOffset));
-}
-
-
-void ArmCodeGenerator::GenerateGetThisFunction(ZoneList<Expression*>* args) {
-  ASSERT(args->length() == 0);
-  __ ldr(r0, MemOperand(pp, JavaScriptFrameConstants::kFunctionOffset));
-  __ push(r0);
-}
-
-
-void ArmCodeGenerator::GenerateSetThis(ZoneList<Expression*>* args) {
-  ASSERT(args->length() == 1);
-  Load(args->at(0));
-  __ ldr(r0, MemOperand(sp, 0));
-  __ str(r0, MemOperand(pp, JavaScriptFrameConstants::kReceiverOffset));
-}
-
-
-void ArmCodeGenerator::GenerateSetArgumentsLength(ZoneList<Expression*>* args) {
-  ASSERT(args->length() == 1);
-  Load(args->at(0));
-  __ pop(r0);
-  __ mov(r0, Operand(r0, LSR, kSmiTagSize));
-  __ str(r0, MemOperand(fp, JavaScriptFrameConstants::kArgsLengthOffset));
-  __ mov(r0, Operand(Smi::FromInt(0)));  // return a meaningful value
-  __ push(r0);
-}
-
-
-void ArmCodeGenerator::GenerateGetArgumentsLength(ZoneList<Expression*>* args) {
-  ASSERT(args->length() == 1);
-  __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kArgsLengthOffset));
-  __ mov(r0, Operand(r0, LSL, kSmiTagSize));
-  __ push(r0);
-}
-
-
 void ArmCodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 1);
   Label leave;
@@ -3803,135 +3876,6 @@
 }
 
 
-void ArmCodeGenerator::GenerateTailCallWithArguments(
-    ZoneList<Expression*>* args) {
-  // r0 = number of arguments (smi)
-  ASSERT(args->length() == 1);
-  Load(args->at(0));
-  __ pop(r0);
-  __ mov(r0, Operand(r0, LSR, kSmiTagSize));
-
-  // r1 = new function (previously written to stack)
-  __ ldr(r1, MemOperand(pp, JavaScriptFrameConstants::kFunctionOffset));
-
-  // Reset parameter pointer and frame pointer to previous frame
-  ExitJSFrame(DO_NOT_RETURN);
-
-  // Jump (tail-call) to the function in register r1.
-  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
-  __ ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
-  __ ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kCodeOffset));
-  __ add(pc, r1, Operand(Code::kHeaderSize - kHeapObjectTag));
-}
-
-
-void ArmCodeGenerator::GenerateSetArgument(ZoneList<Expression*>* args) {
-  ASSERT(args->length() == 3);
-  // r0 = args[i]; r1 = i
-  Comment cmnt(masm_, "[ GenerateSetArgument");
-  Load(args->at(1));  // args[i] (value)
-  Load(args->at(0));  // i
-  __ pop(r1);  // i
-  __ pop(r0);  // value
-#if defined(DEBUG)
-  { Label L;
-    __ tst(r1, Operand(kSmiTagMask));
-    __ b(eq, &L);
-    __ stop("SMI expected");
-    __ bind(&L);
-  }
-#endif  // defined(DEBUG)
-  __ add(r2, pp, Operand(JavaScriptFrameConstants::kParam0Offset));
-  __ str(r0,
-         MemOperand(r2, r1, LSL, kPointerSizeLog2 - kSmiTagSize, NegOffset));
-  __ push(r0);
-}
-
-
-void ArmCodeGenerator::GenerateSquashFrame(ZoneList<Expression*>* args) {
-  ASSERT(args->length() == 2);
-  Load(args->at(0));  // old number of arguments
-  Load(args->at(1));  // new number of arguments, r1 > r0
-  __ pop(r0);
-  __ mov(r0, Operand(r0, LSR, kSmiTagSize));
-  __ pop(r1);
-  __ mov(r1, Operand(r1, LSR, kSmiTagSize));
-  // r1 = number of words to move stack.
-  __ sub(r1, r1, Operand(r0));
-  // r2 is source.
-  __ add(r2, fp, Operand(StandardFrameConstants::kCallerPCOffset));
-  // Move down frame pointer fp.
-  __ add(fp, fp, Operand(r1, LSL, kPointerSizeLog2));
-  // r1 is destination.
-  __ add(r1, fp, Operand(StandardFrameConstants::kCallerPCOffset));
-
-  Label move;
-  __ bind(&move);
-  __ ldr(r3, MemOperand(r2, -kPointerSize, PostIndex));
-  __ str(r3, MemOperand(r1, -kPointerSize, PostIndex));
-  __ cmp(r2, Operand(sp));
-  __ b(ne, &move);
-  __ ldr(r3, MemOperand(r2));
-  __ str(r3, MemOperand(r1));
-
-  // Move down stack pointer esp.
-  __ mov(sp, Operand(r1));
-  // Put something GC-able in r0.
-  __ mov(r0, Operand(Smi::FromInt(0)));
-  __ push(r0);
-}
-
-
-void ArmCodeGenerator::GenerateExpandFrame(ZoneList<Expression*>* args) {
-  ASSERT(args->length() == 2);
-  Load(args->at(1));
-  Load(args->at(0));
-  __ pop(r0);  // new number of arguments
-  __ pop(r1);  // old number of arguments, r1 > r0
-  __ mov(r1, Operand(r1, LSR, kSmiTagSize));
-
-  // r1 = number of words to move stack.
-  __ sub(r1, r1, Operand(r0, LSR, kSmiTagSize));
-  Label end_of_expand_frame;
-  if (FLAG_check_stack) {
-    Label not_too_big;
-    __ sub(r2, sp, Operand(r1, LSL, kPointerSizeLog2));
-    __ mov(ip, Operand(ExternalReference::address_of_stack_guard_limit()));
-    __ ldr(ip, MemOperand(ip));
-    __ cmp(r2, Operand(ip));
-    __ b(gt, &not_too_big);
-    __ mov(r0, Operand(Factory::false_value()));
-    __ b(&end_of_expand_frame);
-    __ bind(&not_too_big);
-  }
-  // r3 is source.
-  __ mov(r3, Operand(sp));
-  // r0 is copy limit + 1 word
-  __ add(r0, fp,
-         Operand(StandardFrameConstants::kCallerPCOffset + kPointerSize));
-  // Move up frame pointer fp.
-  __ sub(fp, fp, Operand(r1, LSL, kPointerSizeLog2));
-  // Move up stack pointer sp.
-  __ sub(sp, sp, Operand(r1, LSL, kPointerSizeLog2));
-  // r1 is destination (r1 = source - r1).
-  __ mov(r2, Operand(0));
-  __ sub(r2, r2, Operand(r1, LSL, kPointerSizeLog2));
-  __ add(r1, r3, Operand(r2));
-
-  Label move;
-  __ bind(&move);
-  __ ldr(r2, MemOperand(r3, kPointerSize, PostIndex));
-  __ str(r2, MemOperand(r1, kPointerSize, PostIndex));
-  __ cmp(r3, Operand(r0));
-  __ b(ne, &move);
-
-  // Put success value in top of stack
-  __ mov(r0, Operand(Factory::true_value()));
-  __ bind(&end_of_expand_frame);
-  __ push(r0);
-}
-
-
 void ArmCodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 1);
   Load(args->at(0));
@@ -3950,7 +3894,6 @@
 }
 
 
-
 // This should generate code that performs a charCodeAt() call or returns
 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
 // It is not yet implemented on ARM, so it always goes to the slow case.
@@ -3961,11 +3904,23 @@
 }
 
 
-
-// This is used in the implementation of apply on ia32 but it is not
-// used on ARM yet.
 void ArmCodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
-  __ stop("ArmCodeGenerator::GenerateIsArray");
+  ASSERT(args->length() == 1);
+  Load(args->at(0));
+  Label answer;
+  // We need the CC bits to come out as not_equal in the case where the
+  // object is a smi.  This can't be done with the usual test opcode so
+  // we use XOR to get the right CC bits.
+  __ pop(r0);
+  __ and_(r1, r0, Operand(kSmiTagMask));
+  __ eor(r1, r1, Operand(kSmiTagMask), SetCC);
+  __ b(ne, &answer);
+  // It is a heap object - get the map.
+  __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
+  __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));
+  // Check if the object is a JS array or not.
+  __ cmp(r1, Operand(JS_ARRAY_TYPE));
+  __ bind(&answer);
   cc_reg_ = eq;
 }
 
@@ -3987,11 +3942,11 @@
 void ArmCodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 1);
 
-  // Load the key onto the stack and set register r1 to the formal
-  // parameters count for the currently executing function.
+  // Satisfy contract with ArgumentsAccessStub:
+  // Load the key into r1 and the formal parameters count into r0.
   Load(args->at(0));
-  __ pop(r0);
-  __ mov(r1, Operand(Smi::FromInt(scope_->num_parameters())));
+  __ pop(r1);
+  __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters())));
 
   // Call the shared stub to get to arguments[key].
   ArgumentsAccessStub stub(false);
@@ -4013,48 +3968,8 @@
 }
 
 
-void ArmCodeGenerator::GenerateShiftDownAndTailCall(
-    ZoneList<Expression*>* args) {
-  // r0 = number of arguments
-  ASSERT(args->length() == 1);
-  Load(args->at(0));
-  __ pop(r0);
-  __ mov(r0, Operand(r0, LSR, kSmiTagSize));
-
-  // Get the 'this' function and exit the frame without returning.
-  __ ldr(r1, MemOperand(pp, JavaScriptFrameConstants::kFunctionOffset));
-  ExitJSFrame(DO_NOT_RETURN);
-  // return address in lr
-
-  // Move arguments one element down the stack.
-  Label move;
-  Label moved;
-  __ sub(r2, r0, Operand(0), SetCC);
-  __ b(eq, &moved);
-  __ bind(&move);
-  __ sub(ip, r2, Operand(1));
-  __ ldr(r3, MemOperand(sp, ip, LSL, kPointerSizeLog2));
-  __ str(r3, MemOperand(sp, r2, LSL, kPointerSizeLog2));
-  __ sub(r2, r2, Operand(1), SetCC);
-  __ b(ne, &move);
-  __ bind(&moved);
-
-  // Remove the TOS (copy of last argument)
-  __ pop();
-
-  // Jump (tail-call) to the function in register r1.
-  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
-  __ ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
-  __ ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kCodeOffset));
-  __ add(pc, r1, Operand(Code::kHeaderSize - kHeapObjectTag));
-
-  return;
-}
-
-
 void ArmCodeGenerator::VisitCallRuntime(CallRuntime* node) {
-  if (CheckForInlineRuntimeCall(node))
-    return;
+  if (CheckForInlineRuntimeCall(node)) return;
 
   ZoneList<Expression*>* args = node->arguments();
   Comment cmnt(masm_, "[ CallRuntime");
@@ -4109,7 +4024,7 @@
       Load(property->obj());
       Load(property->key());
       __ mov(r0, Operand(1));  // not counting receiver
-      __ InvokeBuiltin("DELETE", 1, CALL_JS);
+      __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
 
     } else if (variable != NULL) {
       Slot* slot = variable->slot();
@@ -4118,7 +4033,7 @@
         __ mov(r0, Operand(variable->name()));
         __ push(r0);
         __ mov(r0, Operand(1));  // not counting receiver
-        __ InvokeBuiltin("DELETE", 1, CALL_JS);
+        __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
 
       } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
         // lookup the context holding the named variable
@@ -4131,7 +4046,7 @@
         __ mov(r0, Operand(variable->name()));
         __ push(r0);
         __ mov(r0, Operand(1));  // not counting receiver
-        __ InvokeBuiltin("DELETE", 1, CALL_JS);
+        __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
 
       } else {
         // Default: Result of deleting non-global, not dynamically
@@ -4179,7 +4094,7 @@
 
         __ push(r0);
         __ mov(r0, Operand(0));  // not counting receiver
-        __ InvokeBuiltin("BIT_NOT", 0, CALL_JS);
+        __ InvokeBuiltin(Builtins::BIT_NOT, CALL_JS);
 
         __ b(&continue_label);
         __ bind(&smi_label);
@@ -4202,7 +4117,7 @@
         __ b(eq, &continue_label);
         __ push(r0);
         __ mov(r0, Operand(0));  // not counting receiver
-        __ InvokeBuiltin("TO_NUMBER", 0, CALL_JS);
+        __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS);
         __ bind(&continue_label);
         break;
       }
@@ -4600,13 +4515,13 @@
 
     case Token::IN:
       __ mov(r0, Operand(1));  // not counting receiver
-      __ InvokeBuiltin("IN", 1, CALL_JS);
+      __ InvokeBuiltin(Builtins::IN, CALL_JS);
       __ push(r0);
       break;
 
     case Token::INSTANCEOF:
       __ mov(r0, Operand(1));  // not counting receiver
-      __ InvokeBuiltin("INSTANCE_OF", 1, CALL_JS);
+      __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_JS);
       __ push(r0);
       break;
 
@@ -4625,14 +4540,31 @@
 }
 
 
-void ArmCodeGenerator::EnterJSFrame(int argc) {
-  __ EnterJSFrame(argc);
+void ArmCodeGenerator::EnterJSFrame() {
+#if defined(DEBUG)
+  { Label done, fail;
+    __ tst(r1, Operand(kSmiTagMask));
+    __ b(eq, &fail);
+    __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
+    __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
+    __ cmp(r2, Operand(JS_FUNCTION_TYPE));
+    __ b(eq, &done);
+    __ bind(&fail);
+    __ stop("ArmCodeGenerator::EnterJSFrame - r1 not a function");
+    __ bind(&done);
+  }
+#endif  // DEBUG
+
+  __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
+  __ add(fp, sp, Operand(2 * kPointerSize));  // Adjust FP to point to saved FP.
 }
 
 
-void ArmCodeGenerator::ExitJSFrame(ExitJSFlag flag) {
-  JSExitStub stub(flag);
-  __ CallJSExitStub(&stub);
+void ArmCodeGenerator::ExitJSFrame() {
+  // Drop the execution stack down to the frame pointer and restore the caller
+  // frame pointer and return address.
+  __ mov(sp, fp);
+  __ ldm(ia_w, sp, fp.bit() | lr.bit());
 }
 
 
diff --git a/src/codegen-ia32.cc b/src/codegen-ia32.cc
index 52f5a4e..b6c3ed9 100644
--- a/src/codegen-ia32.cc
+++ b/src/codegen-ia32.cc
@@ -37,34 +37,6 @@
 
 namespace v8 { namespace internal {
 
-DEFINE_bool(trace, false, "trace function calls");
-DEFINE_bool(defer_negation, true, "defer negation operation");
-DECLARE_bool(debug_info);
-DECLARE_bool(debug_code);
-
-#ifdef ENABLE_DISASSEMBLER
-DEFINE_bool(print_code, false, "print generated code");
-#endif
-
-#ifdef DEBUG
-DECLARE_bool(gc_greedy);
-DEFINE_bool(trace_codegen, false,
-            "print name of functions for which code is generated");
-DEFINE_bool(print_builtin_code, false, "print generated code for builtins");
-DEFINE_bool(print_source, false, "pretty print source code");
-DEFINE_bool(print_builtin_source, false,
-            "pretty print source code for builtins");
-DEFINE_bool(print_ast, false, "print source AST");
-DEFINE_bool(print_builtin_ast, false, "print source AST for builtins");
-DEFINE_bool(trace_calls, false, "trace calls");
-DEFINE_bool(trace_builtin_calls, false, "trace builtins calls");
-DEFINE_string(stop_at, "", "function name where to insert a breakpoint");
-#endif  // DEBUG
-
-
-DEFINE_bool(check_stack, true,
-            "check stack for overflow, interrupt, breakpoint");
-
 #define TOS (Operand(esp, 0))
 
 
@@ -107,35 +79,46 @@
 };
 
 
-// -----------------------------------------------------------------------------
+// -------------------------------------------------------------------------
 // Code generation state
 
+// The state is passed down the AST by the code generator.  It is passed
+// implicitly (in a member variable) to the non-static code generator member
+// functions, and explicitly (as an argument) to the static member functions
+// and the AST node member functions.
+//
+// The state is threaded through the call stack.  Constructing a state
+// implicitly pushes it on the owning code generator's stack of states, and
+// destroying one implicitly pops it.
+
 class CodeGenState BASE_EMBEDDED {
  public:
   enum AccessType {
     UNDEFINED,
     LOAD,
-    LOAD_TYPEOF_EXPR,
-    STORE,
-    INIT_CONST
+    LOAD_TYPEOF_EXPR
   };
 
-  CodeGenState()
-      : access_(UNDEFINED),
-        ref_(NULL),
-        true_target_(NULL),
-        false_target_(NULL) {
-  }
+  // Create an initial code generator state.  Destroying the initial state
+  // leaves the code generator with a NULL state.
+  explicit CodeGenState(Ia32CodeGenerator* owner);
 
-  CodeGenState(AccessType access,
-               Reference* ref,
+  // Create a code generator state based on a code generator's current
+  // state.  The new state has its own access type and pair of branch
+  // labels, and no reference.
+  CodeGenState(Ia32CodeGenerator* owner,
+               AccessType access,
                Label* true_target,
-               Label* false_target)
-      : access_(access),
-        ref_(ref),
-        true_target_(true_target),
-        false_target_(false_target) {
-  }
+               Label* false_target);
+
+  // Create a code generator state based on a code generator's current
+  // state.  The new state has an access type of LOAD, its own reference,
+  // and inherits the pair of branch labels of the current state.
+  CodeGenState(Ia32CodeGenerator* owner, Reference* ref);
+
+  // Destroy a code generator state and restore the owning code generator's
+  // previous state.
+  ~CodeGenState();
 
   AccessType access() const { return access_; }
   Reference* ref() const { return ref_; }
@@ -143,10 +126,12 @@
   Label* false_target() const { return false_target_; }
 
  private:
+  Ia32CodeGenerator* owner_;
   AccessType access_;
   Reference* ref_;
   Label* true_target_;
   Label* false_target_;
+  CodeGenState* previous_;
 };
 
 
@@ -161,6 +146,9 @@
 
   MacroAssembler* masm()  { return masm_; }
 
+  CodeGenState* state() { return state_; }
+  void set_state(CodeGenState* state) { state_ = state; }
+
  private:
   // Assembler
   MacroAssembler* masm_;  // to generate code
@@ -187,7 +175,6 @@
   // The following are used by class Reference.
   void LoadReference(Reference* ref);
   void UnloadReference(Reference* ref);
-  friend class Reference;
 
   // State
   bool has_cc() const  { return cc_reg_ >= 0; }
@@ -198,26 +185,39 @@
   Label* false_target() const  { return state_->false_target(); }
 
   // Expressions
-  Operand GlobalObject() const  {
+  Operand GlobalObject() const {
     return ContextOperand(esi, Context::GLOBAL_INDEX);
   }
 
-  // Support functions for accessing parameters.
+  // Support functions for accessing parameters.  Static versions can
+  // require some code generator state to be passed in as arguments.
+  static Operand ParameterOperand(Scope* scope, int index) {
+    ASSERT(-2 <= index && index < scope->num_parameters());
+    return Operand(ebp, (1 + scope->num_parameters() - index) * kPointerSize);
+  }
+
   Operand ParameterOperand(int index) const {
-    ASSERT(-2 <= index && index < scope_->num_parameters());
-    return Operand(ebp, (1 + scope_->num_parameters() - index) * kPointerSize);
+    return ParameterOperand(scope_, index);
   }
 
   Operand ReceiverOperand() const { return ParameterOperand(-1); }
+
   Operand FunctionOperand() const {
     return Operand(ebp, JavaScriptFrameConstants::kFunctionOffset);
   }
 
-  Operand ContextOperand(Register context, int index) const {
+  static Operand ContextOperand(Register context, int index) {
     return Operand(context, Context::SlotOffset(index));
   }
 
-  Operand SlotOperand(Slot* slot, Register tmp);
+  static Operand SlotOperand(MacroAssembler* masm,
+                             Scope* scope,
+                             Slot* slot,
+                             Register tmp);
+
+  Operand SlotOperand(Slot* slot, Register tmp) {
+    return SlotOperand(masm_, scope_, slot, tmp);
+  }
 
   void LoadCondition(Expression* x,
                      CodeGenState::AccessType access,
@@ -237,21 +237,48 @@
   void LoadTypeofExpression(Expression* x);
 
   // References
-  void AccessReference(Reference* ref, CodeGenState::AccessType access);
 
-  void GetValue(Reference* ref) { AccessReference(ref, CodeGenState::LOAD); }
-  void SetValue(Reference* ref) { AccessReference(ref, CodeGenState::STORE); }
-  void InitConst(Reference* ref) {
-    AccessReference(ref, CodeGenState::INIT_CONST);
+  // Generate code to fetch the value of a reference.  The reference is
+  // expected to be on top of the expression stack.  It is left in place and
+  // its value is pushed on top of it.
+  void GetValue(Reference* ref) {
+    ASSERT(!has_cc());
+    ASSERT(!ref->is_illegal());
+    CodeGenState new_state(this, ref);
+    Visit(ref->expression());
   }
 
+  // Generate code to store a value in a reference.  The stored value is
+  // expected on top of the expression stack, with the reference immediately
+  // below it.  The expression stack is left unchanged.
+  void SetValue(Reference* ref) {
+    ASSERT(!has_cc());
+    ASSERT(!ref->is_illegal());
+    ref->expression()->GenerateStoreCode(masm_, scope_, ref, NOT_CONST_INIT);
+  }
+
+  // Same as SetValue, used to set the initial value of a constant.
+  void InitConst(Reference* ref) {
+    ASSERT(!has_cc());
+    ASSERT(!ref->is_illegal());
+    ref->expression()->GenerateStoreCode(masm_, scope_, ref, CONST_INIT);
+  }
+
+  // Generate code to fetch a value from a property of a reference.  The
+  // reference is expected on top of the expression stack.  It is left in
+  // place and its value is pushed on top of it.
+  void GetReferenceProperty(Expression* key);
+
+  // Generate code to store a value in a property of a reference.  The
+  // stored value is expected on top of the expression stack, with the
+  // reference immediately below it.  The expression stack is left
+  // unchanged.
+  static void SetReferenceProperty(MacroAssembler* masm,
+                                   Reference* ref,
+                                   Expression* key);
+
   void ToBoolean(Label* true_target, Label* false_target);
 
-
-  // Access property from the reference (must be at the TOS).
-  void AccessReferenceProperty(Expression* key,
-                               CodeGenState::AccessType access);
-
   void GenericBinaryOperation(
       Token::Value op,
       const OverwriteMode overwrite_mode = NO_OVERWRITE);
@@ -293,16 +320,6 @@
   void EnterJSFrame();
   void ExitJSFrame();
 
-  virtual void GenerateShiftDownAndTailCall(ZoneList<Expression*>* args);
-  virtual void GenerateSetThisFunction(ZoneList<Expression*>* args);
-  virtual void GenerateGetThisFunction(ZoneList<Expression*>* args);
-  virtual void GenerateSetThis(ZoneList<Expression*>* args);
-  virtual void GenerateGetArgumentsLength(ZoneList<Expression*>* args);
-  virtual void GenerateSetArgumentsLength(ZoneList<Expression*>* args);
-  virtual void GenerateTailCallWithArguments(ZoneList<Expression*>* args);
-  virtual void GenerateSetArgument(ZoneList<Expression*>* args);
-  virtual void GenerateSquashFrame(ZoneList<Expression*>* args);
-  virtual void GenerateExpandFrame(ZoneList<Expression*>* args);
   virtual void GenerateIsSmi(ZoneList<Expression*>* args);
   virtual void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
   virtual void GenerateIsArray(ZoneList<Expression*>* args);
@@ -316,9 +333,59 @@
   virtual void GenerateFastCharCodeAt(ZoneList<Expression*>* args);
 
   virtual void GenerateObjectEquals(ZoneList<Expression*>* args);
+
+  friend class Reference;
+  friend class Property;
+  friend class VariableProxy;
+  friend class Slot;
 };
 
 
+// -------------------------------------------------------------------------
+// CodeGenState implementation.
+
+CodeGenState::CodeGenState(Ia32CodeGenerator* owner)
+    : owner_(owner),
+      access_(UNDEFINED),
+      ref_(NULL),
+      true_target_(NULL),
+      false_target_(NULL),
+      previous_(NULL) {
+  owner_->set_state(this);
+}
+
+
+CodeGenState::CodeGenState(Ia32CodeGenerator* owner,
+                           AccessType access,
+                           Label* true_target,
+                           Label* false_target)
+    : owner_(owner),
+      access_(access),
+      ref_(NULL),
+      true_target_(true_target),
+      false_target_(false_target),
+      previous_(owner->state()) {
+  owner_->set_state(this);
+}
+
+
+CodeGenState::CodeGenState(Ia32CodeGenerator* owner, Reference* ref)
+    : owner_(owner),
+      access_(LOAD),
+      ref_(ref),
+      true_target_(owner->state()->true_target_),
+      false_target_(owner->state()->false_target_),
+      previous_(owner->state()) {
+  owner_->set_state(this);
+}
+
+
+CodeGenState::~CodeGenState() {
+  ASSERT(owner_->state() == this);
+  owner_->set_state(previous_);
+}
+
+
 // -----------------------------------------------------------------------------
 // Ia32CodeGenerator implementation
 
@@ -437,8 +504,7 @@
   ZoneList<Statement*>* body = fun->body();
 
   // Initialize state.
-  { CodeGenState state;
-    state_ = &state;
+  { CodeGenState state(this);
     scope_ = scope;
     cc_reg_ = no_condition;
 
@@ -622,8 +688,6 @@
         VisitReturnStatement(&statement);
       }
     }
-
-    state_ = NULL;
   }
 
   // Code generation state must be reset.
@@ -633,7 +697,10 @@
 }
 
 
-Operand Ia32CodeGenerator::SlotOperand(Slot* slot, Register tmp) {
+Operand Ia32CodeGenerator::SlotOperand(MacroAssembler* masm,
+                                       Scope* scope,
+                                       Slot* slot,
+                                       Register tmp) {
   // Currently, this assertion will fail if we try to assign to
   // a constant variable that is constant because it is read-only
   // (such as the variable referring to a named function expression).
@@ -645,10 +712,10 @@
   ASSERT(slot != NULL);
   int index = slot->index();
   switch (slot->type()) {
-    case Slot::PARAMETER: return ParameterOperand(index);
+    case Slot::PARAMETER: return ParameterOperand(scope, index);
 
     case Slot::LOCAL: {
-      ASSERT(0 <= index && index < scope_->num_stack_slots());
+      ASSERT(0 <= index && index < scope->num_stack_slots());
       const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
       return Operand(ebp, kLocal0Offset - index * kPointerSize);
     }
@@ -657,15 +724,15 @@
       // Follow the context chain if necessary.
       ASSERT(!tmp.is(esi));  // do not overwrite context register
       Register context = esi;
-      int chain_length = scope_->ContextChainLength(slot->var()->scope());
+      int chain_length = scope->ContextChainLength(slot->var()->scope());
       for (int i = chain_length; i-- > 0;) {
         // Load the closure.
         // (All contexts, even 'with' contexts, have a closure,
         // and it is the same for all contexts inside a function.
         // There is no need to go to the function context first.)
-        __ mov(tmp, ContextOperand(context, Context::CLOSURE_INDEX));
+        masm->mov(tmp, ContextOperand(context, Context::CLOSURE_INDEX));
         // Load the function context (which is the incoming, outer context).
-        __ mov(tmp, FieldOperand(tmp, JSFunction::kContextOffset));
+        masm->mov(tmp, FieldOperand(tmp, JSFunction::kContextOffset));
         context = tmp;
       }
       // We may have a 'with' context now. Get the function context.
@@ -675,7 +742,7 @@
       // cause the function context of a function context is itself. Before
       // deleting this mov we should try to create a counter-example first,
       // though...)
-      __ mov(tmp, ContextOperand(context, Context::FCONTEXT_INDEX));
+      masm->mov(tmp, ContextOperand(context, Context::FCONTEXT_INDEX));
       return ContextOperand(tmp, index);
     }
 
@@ -700,11 +767,9 @@
          access == CodeGenState::LOAD_TYPEOF_EXPR);
   ASSERT(!has_cc() && !is_referenced());
 
-  CodeGenState* old_state = state_;
-  CodeGenState new_state(access, NULL, true_target, false_target);
-  state_ = &new_state;
-  Visit(x);
-  state_ = old_state;
+  { CodeGenState new_state(this, access, true_target, false_target);
+    Visit(x);
+  }
   if (force_cc && !has_cc()) {
     ToBoolean(true_target, false_target);
   }
@@ -852,15 +917,109 @@
 }
 
 
-void Ia32CodeGenerator::AccessReference(Reference* ref,
-                                        CodeGenState::AccessType access) {
-  ASSERT(!has_cc());
-  ASSERT(ref->type() != Reference::ILLEGAL);
-  CodeGenState* old_state = state_;
-  CodeGenState new_state(access, ref, true_target(), false_target());
-  state_ = &new_state;
-  Visit(ref->expression());
-  state_ = old_state;
+void Property::GenerateStoreCode(MacroAssembler* masm,
+                                 Scope* scope,
+                                 Reference* ref,
+                                 InitState init_state) {
+  Comment cmnt(masm, "[ Store to Property");
+  masm->RecordPosition(position());
+  Ia32CodeGenerator::SetReferenceProperty(masm, ref, key());
+}
+
+
+void VariableProxy::GenerateStoreCode(MacroAssembler* masm,
+                                      Scope* scope,
+                                      Reference* ref,
+                                      InitState init_state) {
+  Comment cmnt(masm, "[ Store to VariableProxy");
+  Variable* node = var();
+
+  Expression* expr = node->rewrite();
+  if (expr != NULL) {
+    expr->GenerateStoreCode(masm, scope, ref, init_state);
+  } else {
+    ASSERT(node->is_global());
+    if (node->AsProperty() != NULL) {
+      masm->RecordPosition(node->AsProperty()->position());
+    }
+    Ia32CodeGenerator::SetReferenceProperty(masm, ref,
+                                            new Literal(node->name()));
+  }
+}
+
+
+void Slot::GenerateStoreCode(MacroAssembler* masm,
+                             Scope* scope,
+                             Reference* ref,
+                             InitState init_state) {
+  Comment cmnt(masm, "[ Store to Slot");
+
+  if (type() == Slot::LOOKUP) {
+    ASSERT(var()->mode() == Variable::DYNAMIC);
+
+    // For now, just do a runtime call.
+    masm->push(Operand(esi));
+    masm->push(Immediate(var()->name()));
+
+    if (init_state == CONST_INIT) {
+      // Same as the case for a normal store, but ignores attribute
+      // (e.g. READ_ONLY) of context slot so that we can initialize const
+      // properties (introduced via eval("const foo = (some expr);")). Also,
+      // uses the current function context instead of the top context.
+      //
+      // Note that we must declare the foo upon entry of eval(), via a
+      // context slot declaration, but we cannot initialize it at the same
+      // time, because the const declaration may be at the end of the eval
+      // code (sigh...) and the const variable may have been used before
+      // (where its value is 'undefined'). Thus, we can only do the
+      // initialization when we actually encounter the expression and when
+      // the expression operands are defined and valid, and thus we need the
+      // split into 2 operations: declaration of the context slot followed
+      // by initialization.
+      masm->CallRuntime(Runtime::kInitializeConstContextSlot, 3);
+    } else {
+      masm->CallRuntime(Runtime::kStoreContextSlot, 3);
+    }
+    // Storing a variable must keep the (new) value on the expression
+    // stack. This is necessary for compiling assignment expressions.
+    masm->push(eax);
+
+  } else {
+    ASSERT(var()->mode() != Variable::DYNAMIC);
+
+    Label exit;
+    if (init_state == CONST_INIT) {
+      ASSERT(var()->mode() == Variable::CONST);
+      // Only the first const initialization must be executed (the slot
+      // still contains 'the hole' value). When the assignment is executed,
+      // the code is identical to a normal store (see below).
+      Comment cmnt(masm, "[ Init const");
+      masm->mov(eax, Ia32CodeGenerator::SlotOperand(masm, scope, this, ecx));
+      masm->cmp(eax, Factory::the_hole_value());
+      masm->j(not_equal, &exit);
+    }
+
+    // We must execute the store.
+    // Storing a variable must keep the (new) value on the stack. This is
+    // necessary for compiling assignment expressions.  ecx may be loaded
+    // with context; used below in RecordWrite.
+    //
+    // Note: We will reach here even with node->var()->mode() ==
+    // Variable::CONST because of const declarations which will initialize
+    // consts to 'the hole' value and by doing so, end up calling this
+    // code.
+    masm->pop(eax);
+    masm->mov(Ia32CodeGenerator::SlotOperand(masm, scope, this, ecx), eax);
+    masm->push(eax);  // RecordWrite may destroy the value in eax.
+    if (type() == Slot::CONTEXT) {
+      // ecx is loaded with context when calling SlotOperand above.
+      int offset = FixedArray::kHeaderSize + index() * kPointerSize;
+      masm->RecordWrite(ecx, offset, eax, ebx);
+    }
+    // If we definitely did not jump over the assignment, we do not need to
+    // bind the exit label.  Doing so can defeat peephole optimization.
+    if (init_state == CONST_INIT) masm->bind(&exit);
+  }
 }
 
 
@@ -991,18 +1150,53 @@
 }
 
 
-void Ia32CodeGenerator::AccessReferenceProperty(
-    Expression* key,
-    CodeGenState::AccessType access) {
+void Ia32CodeGenerator::GetReferenceProperty(Expression* key) {
+  ASSERT(!ref()->is_illegal());
   Reference::Type type = ref()->type();
-  ASSERT(type != Reference::ILLEGAL);
 
-  // TODO(1241834): Make sure that this is sufficient. If there is a chance
-  // that reference errors can be thrown below, we must distinguish
-  // between the 2 kinds of loads (typeof expression loads must not
-  // throw a reference error).
-  bool is_load = (access == CodeGenState::LOAD ||
-                  access == CodeGenState::LOAD_TYPEOF_EXPR);
+  // TODO(1241834): Make sure that this it is safe to ignore the distinction
+  // between access types LOAD and LOAD_TYPEOF_EXPR. If there is a chance
+  // that reference errors can be thrown below, we must distinguish between
+  // the two kinds of loads (typeof expression loads must not throw a
+  // reference error).
+  if (type == Reference::NAMED) {
+    // Compute the name of the property.
+    Literal* literal = key->AsLiteral();
+    Handle<String> name(String::cast(*literal->handle()));
+
+    Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
+    Variable* var = ref()->expression()->AsVariableProxy()->AsVariable();
+    // Setup the name register.
+    __ Set(ecx, Immediate(name));
+    if (var != NULL) {
+      ASSERT(var->is_global());
+      __ call(ic, code_target_context);
+    } else {
+      __ call(ic, code_target);
+    }
+  } else {
+    // Access keyed property.
+    ASSERT(type == Reference::KEYED);
+
+    // Call IC code.
+    Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
+    Variable* var = ref()->expression()->AsVariableProxy()->AsVariable();
+    if (var != NULL) {
+      ASSERT(var->is_global());
+      __ call(ic, code_target_context);
+    } else {
+      __ call(ic, code_target);
+    }
+  }
+  __ push(eax);  // IC call leaves result in eax, push it out
+}
+
+
+void Ia32CodeGenerator::SetReferenceProperty(MacroAssembler* masm,
+                                             Reference* ref,
+                                             Expression* key) {
+  ASSERT(!ref->is_illegal());
+  Reference::Type type = ref->type();
 
   if (type == Reference::NAMED) {
     // Compute the name of the property.
@@ -1010,48 +1204,23 @@
     Handle<String> name(String::cast(*literal->handle()));
 
     // Call the appropriate IC code.
-    if (is_load) {
-      Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
-      Variable* var = ref()->expression()->AsVariableProxy()->AsVariable();
-      // Setup the name register.
-      __ Set(ecx, Immediate(name));
-      if (var != NULL) {
-        ASSERT(var->is_global());
-        __ call(ic, code_target_context);
-      } else {
-        __ call(ic, code_target);
-      }
-    } else {
-      Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
-      // TODO(1222589): Make the IC grab the values from the stack.
-      __ pop(eax);
-      // Setup the name register.
-      __ Set(ecx, Immediate(name));
-      __ call(ic, code_target);
-    }
+    Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+    // TODO(1222589): Make the IC grab the values from the stack.
+    masm->pop(eax);
+    // Setup the name register.
+    masm->Set(ecx, Immediate(name));
+    masm->call(ic, code_target);
   } else {
     // Access keyed property.
     ASSERT(type == Reference::KEYED);
 
-    if (is_load) {
-      // Call IC code.
-      Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
-      Variable* var = ref()->expression()->AsVariableProxy()->AsVariable();
-      if (var != NULL) {
-        ASSERT(var->is_global());
-        __ call(ic, code_target_context);
-      } else {
-        __ call(ic, code_target);
-      }
-    } else {
-      // Call IC code.
-      Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
-      // TODO(1222589): Make the IC grab the values from the stack.
-      __ pop(eax);
-      __ call(ic, code_target);
-    }
+    // Call IC code.
+    Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
+    // TODO(1222589): Make the IC grab the values from the stack.
+    masm->pop(eax);
+    masm->call(ic, code_target);
   }
-  __ push(eax);  // IC call leaves result in eax, push it out
+  masm->push(eax);  // IC call leaves result in eax, push it out
 }
 
 
@@ -2748,19 +2917,14 @@
     Comment cmnt(masm_, "[ case clause");
 
     if (clause->is_default()) {
+      // Continue matching cases. The program will execute the default case's
+      // statements if it does not match any of the cases.
+      __ jmp(&next);
+
       // Bind the default case label, so we can branch to it when we
       // have compared against all other cases.
       ASSERT(default_case.is_unused());  // at most one default clause
-
-      // If the default case is the first (but not only) case, we have
-      // to jump past it for now. Once we're done with the remaining
-      // clauses, we'll branch back here. If it isn't the first case,
-      // we jump past it by avoiding to chain it into the next chain.
-      if (length > 1) {
-        if (i == 0) __ jmp(&next);
-        __ bind(&default_case);
-      }
-
+      __ bind(&default_case);
     } else {
       __ bind(&next);
       next.Unuse();
@@ -2769,11 +2933,16 @@
       Load(clause->label());
       Comparison(equal, true);
       Branch(false, &next);
-      // Entering the case statement -> remove the switch value from the stack
-      __ pop(eax);
     }
 
+    // Entering the case statement for the first time. Remove the switch value
+    // from the stack.
+    __ pop(eax);
+
     // Generate code for the body.
+    // This is also the target for the fall through from the previous case's
+    // statements which has to skip over the matching code and the popping of
+    // the switch value.
     __ bind(&fall_through);
     fall_through.Unuse();
     VisitStatements(clause->statements());
@@ -2781,10 +2950,14 @@
   }
 
   __ bind(&next);
-  // Reached the end of the case statements -> remove the switch value
-  // from the stack
-  __ pop(eax);  // Pop(no_reg)
-  if (default_case.is_bound()) __ jmp(&default_case);
+  // Reached the end of the case statements without matching any of the cases.
+  if (default_case.is_bound()) {
+    // A default case exists -> execute its statements.
+    __ jmp(&default_case);
+  } else {
+    // Remove the switch value from the stack.
+    __ pop(eax);
+  }
 
   __ bind(&fall_through);
   __ bind(node->break_target());
@@ -3325,6 +3498,7 @@
 
 
 void Ia32CodeGenerator::VisitSlot(Slot* node) {
+  ASSERT(access() != CodeGenState::UNDEFINED);
   Comment cmnt(masm_, "[ Slot");
 
   if (node->type() == Slot::LOOKUP) {
@@ -3334,151 +3508,56 @@
     __ push(Operand(esi));
     __ push(Immediate(node->var()->name()));
 
-    switch (access()) {
-      case CodeGenState::UNDEFINED:
-        UNREACHABLE();
-        break;
-
-      case CodeGenState::LOAD:
-        __ CallRuntime(Runtime::kLoadContextSlot, 2);
-        __ push(eax);
-        // result (TOS) is the value that was loaded
-        break;
-
-      case CodeGenState::LOAD_TYPEOF_EXPR:
-        __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
-        __ push(eax);
-        // result (TOS) is the value that was loaded
-        break;
-
-      case CodeGenState::STORE:
-        // Storing a variable must keep the (new) value on the
-        // stack. This is necessary for compiling assignment
-        // expressions.
-        __ CallRuntime(Runtime::kStoreContextSlot, 3);
-        __ push(eax);
-        // result (TOS) is the value that was stored
-        break;
-
-      case CodeGenState::INIT_CONST:
-        // Same as STORE but ignores attribute (e.g. READ_ONLY) of
-        // context slot so that we can initialize const properties
-        // (introduced via eval("const foo = (some expr);")). Also,
-        // uses the current function context instead of the top
-        // context.
-        //
-        // Note that we must declare the foo upon entry of eval(),
-        // via a context slot declaration, but we cannot initialize
-        // it at the same time, because the const declaration may
-        // be at the end of the eval code (sigh...) and the const
-        // variable may have been used before (where its value is
-        // 'undefined'). Thus, we can only do the initialization
-        // when we actually encounter the expression and when the
-        // expression operands are defined and valid, and thus we
-        // need the split into 2 operations: declaration of the
-        // context slot followed by initialization.
-        //
-        __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
-        __ push(eax);
-        break;
+    if (access() == CodeGenState::LOAD) {
+      __ CallRuntime(Runtime::kLoadContextSlot, 2);
+    } else {
+      ASSERT(access() == CodeGenState::LOAD_TYPEOF_EXPR);
+      __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
     }
+    __ push(eax);
 
   } else {
-    // Note: We would like to keep the assert below, but it fires because
-    // of some nasty code in LoadTypeofExpression() which should be removed...
+    // Note: We would like to keep the assert below, but it fires because of
+    // some nasty code in LoadTypeofExpression() which should be removed...
     // ASSERT(node->var()->mode() != Variable::DYNAMIC);
 
-    switch (access()) {
-      case CodeGenState::UNDEFINED:
-        UNREACHABLE();
-        break;
-
-      case CodeGenState::LOAD:  // fall through
-      case CodeGenState::LOAD_TYPEOF_EXPR:
-        if (node->var()->mode() == Variable::CONST) {
-          // Const slots may contain 'the hole' value (the constant hasn't
-          // been initialized yet) which needs to be converted into the
-          // 'undefined' value.
-          Comment cmnt(masm_, "[ Load const");
-          Label L;
-          __ mov(eax, SlotOperand(node, ecx));
-          __ cmp(eax, Factory::the_hole_value());
-          __ j(not_equal, &L);
-          __ mov(eax, Factory::undefined_value());
-          __ bind(&L);
-          __ push(eax);
-        } else {
-          __ push(SlotOperand(node, ecx));
-        }
-        break;
-
-      case CodeGenState::INIT_CONST:
-        ASSERT(node->var()->mode() == Variable::CONST);
-        // Only the first const initialization must be executed (the slot
-        // still contains 'the hole' value). When the assignment is executed,
-        // the code is identical to a normal store (see below).
-        { Comment cmnt(masm_, "[ Init const");
-          Label L;
-          __ mov(eax, SlotOperand(node, ecx));
-          __ cmp(eax, Factory::the_hole_value());
-          __ j(not_equal, &L);
-          // We must execute the store.
-          __ mov(eax, TOS);
-          __ mov(SlotOperand(node, ecx), eax);
-          if (node->type() == Slot::CONTEXT) {
-            // ecx is loaded with context when calling SlotOperand above.
-            int offset = FixedArray::kHeaderSize + node->index() * kPointerSize;
-            __ RecordWrite(ecx, offset, eax, ebx);
-          }
-          __ bind(&L);
-        }
-        break;
-
-      case CodeGenState::STORE:
-        // Storing a variable must keep the (new) value on the stack. This
-        // is necessary for compiling assignment expressions.
-        // ecx may be loaded with context; used below in RecordWrite.
-        //
-        // Note: We will reach here even with node->var()->mode() ==
-        // Variable::CONST because of const declarations which will
-        // initialize consts to 'the hole' value and by doing so, end
-        // up calling this code.
-        __ pop(eax);
-        __ mov(SlotOperand(node, ecx), eax);
-        __ push(eax);  // RecordWrite may destroy the value in eax.
-        if (node->type() == Slot::CONTEXT) {
-          // ecx is loaded with context when calling SlotOperand above.
-          int offset = FixedArray::kHeaderSize + node->index() * kPointerSize;
-          __ RecordWrite(ecx, offset, eax, ebx);
-        }
-        break;
+    if (node->var()->mode() == Variable::CONST) {
+      // Const slots may contain 'the hole' value (the constant hasn't been
+      // initialized yet) which needs to be converted into the 'undefined'
+      // value.
+      Comment cmnt(masm_, "[ Load const");
+      Label L;
+      __ mov(eax, SlotOperand(node, ecx));
+      __ cmp(eax, Factory::the_hole_value());
+      __ j(not_equal, &L);
+      __ mov(eax, Factory::undefined_value());
+      __ bind(&L);
+      __ push(eax);
+    } else {
+      __ push(SlotOperand(node, ecx));
     }
   }
 }
 
 
-void Ia32CodeGenerator::VisitVariableProxy(VariableProxy* proxy_node) {
+void Ia32CodeGenerator::VisitVariableProxy(VariableProxy* node) {
   Comment cmnt(masm_, "[ VariableProxy");
-  Variable* node = proxy_node->var();
+  Variable* var_node = node->var();
 
-  Expression* x = node->rewrite();
-  if (x != NULL) {
-    Visit(x);
-    return;
-  }
-
-  ASSERT(node->is_global());
-  if (is_referenced()) {
-    if (node->AsProperty() != NULL) {
-      __ RecordPosition(node->AsProperty()->position());
-    }
-    AccessReferenceProperty(new Literal(node->name()), access());
-
+  Expression* expr = var_node->rewrite();
+  if (expr != NULL) {
+    Visit(expr);
   } else {
-    // All stores are through references.
-    ASSERT(access() != CodeGenState::STORE);
-    Reference property(this, proxy_node);
-    GetValue(&property);
+    ASSERT(var_node->is_global());
+    if (is_referenced()) {
+      if (var_node->AsProperty() != NULL) {
+        __ RecordPosition(var_node->AsProperty()->position());
+      }
+      GetReferenceProperty(new Literal(var_node->name()));
+    } else {
+      Reference property(this, node);
+      GetValue(&property);
+    }
   }
 }
 
@@ -3784,10 +3863,8 @@
 
   if (is_referenced()) {
     __ RecordPosition(node->position());
-    AccessReferenceProperty(node->key(), access());
+    GetReferenceProperty(node->key());
   } else {
-    // All stores are through references.
-    ASSERT(access() != CodeGenState::STORE);
     Reference property(this, node);
     __ RecordPosition(node->position());
     GetValue(&property);
@@ -3952,70 +4029,6 @@
 }
 
 
-void Ia32CodeGenerator::GenerateSetThisFunction(ZoneList<Expression*>* args) {
-  // Not used on IA-32 anymore. Should go away soon.
-  __ int3();
-}
-
-
-void Ia32CodeGenerator::GenerateGetThisFunction(ZoneList<Expression*>* args) {
-  // Not used on IA-32 anymore. Should go away soon.
-  __ int3();
-}
-
-
-void Ia32CodeGenerator::GenerateSetThis(ZoneList<Expression*>* args) {
-  // Not used on IA-32 anymore. Should go away soon.
-  __ int3();
-}
-
-
-void Ia32CodeGenerator::GenerateSetArgumentsLength(
-    ZoneList<Expression*>* args) {
-  // Not used on IA-32 anymore. Should go away soon.
-  __ int3();
-}
-
-
-void Ia32CodeGenerator::GenerateGetArgumentsLength(
-    ZoneList<Expression*>* args) {
-  // Not used on IA-32 anymore. Should go away soon.
-  __ int3();
-}
-
-
-void Ia32CodeGenerator::GenerateTailCallWithArguments(
-     ZoneList<Expression*>* args) {
-  // Not used on IA-32 anymore. Should go away soon.
-  __ int3();
-}
-
-
-void Ia32CodeGenerator::GenerateSetArgument(ZoneList<Expression*>* args) {
-  // Not used on IA-32 anymore. Should go away soon.
-  __ int3();
-}
-
-
-void Ia32CodeGenerator::GenerateSquashFrame(ZoneList<Expression*>* args) {
-  // Not used on IA-32 anymore. Should go away soon.
-  __ int3();
-}
-
-
-void Ia32CodeGenerator::GenerateExpandFrame(ZoneList<Expression*>* args) {
-  // Not used on IA-32 anymore. Should go away soon.
-  __ int3();
-}
-
-
-void Ia32CodeGenerator::GenerateShiftDownAndTailCall(
-    ZoneList<Expression*>* args) {
-  // Not used on IA-32 anymore. Should go away soon.
-  __ int3();
-}
-
-
 void Ia32CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 1);
   Load(args->at(0));
diff --git a/src/codegen.cc b/src/codegen.cc
index 3631a95..a7123b0 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -34,11 +34,6 @@
 
 namespace v8 { namespace internal {
 
-
-DEFINE_bool(lazy, true, "use lazy compilation");
-DEFINE_bool(debug_info, true, "add debug information to compiled functions");
-
-
 DeferredCode::DeferredCode(CodeGenerator* generator)
   : masm_(generator->masm()),
     generator_(generator),
@@ -221,26 +216,6 @@
   // for implementing Function.prototype.call() and
   // Function.prototype.apply().
   static const InlineRuntimeLUT kInlineRuntimeLUT[] = {
-    {&v8::internal::CodeGenerator::GenerateShiftDownAndTailCall,
-     "_ShiftDownAndTailCall"},
-    {&v8::internal::CodeGenerator::GenerateSetThisFunction,
-     "_SetThisFunction"},
-    {&v8::internal::CodeGenerator::GenerateGetThisFunction,
-     "_GetThisFunction"},
-    {&v8::internal::CodeGenerator::GenerateSetThis,
-     "_SetThis"},
-    {&v8::internal::CodeGenerator::GenerateGetArgumentsLength,
-     "_GetArgumentsLength"},
-    {&v8::internal::CodeGenerator::GenerateSetArgumentsLength,
-     "_SetArgumentsLength"},
-    {&v8::internal::CodeGenerator::GenerateTailCallWithArguments,
-     "_TailCallWithArguments"},
-    {&v8::internal::CodeGenerator::GenerateSetArgument,
-     "_SetArgument"},
-    {&v8::internal::CodeGenerator::GenerateSquashFrame,
-     "_SquashFrame"},
-    {&v8::internal::CodeGenerator::GenerateExpandFrame,
-     "_ExpandFrame"},
     {&v8::internal::CodeGenerator::GenerateIsSmi,
      "_IsSmi"},
     {&v8::internal::CodeGenerator::GenerateIsNonNegativeSmi,
diff --git a/src/codegen.h b/src/codegen.h
index 8f0e265..43d780e 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -41,7 +41,6 @@
 //       install extensions with lazy compilation enabled. At the
 //       moment, this doesn't work for the extensions in Google3,
 //       and we can only run the tests with --nolazy.
-DECLARE_bool(lazy);
 
 
 // Forward declaration.
@@ -148,16 +147,7 @@
   // name/value pairs.
   virtual void DeclareGlobals(Handle<FixedArray> pairs) = 0;
 
-  virtual void GenerateShiftDownAndTailCall(ZoneList<Expression*>* args) = 0;
-  virtual void GenerateSetThisFunction(ZoneList<Expression*>* args) = 0;
-  virtual void GenerateGetThisFunction(ZoneList<Expression*>* args) = 0;
-  virtual void GenerateSetThis(ZoneList<Expression*>* args) = 0;
-  virtual void GenerateGetArgumentsLength(ZoneList<Expression*>* args) = 0;
-  virtual void GenerateSetArgumentsLength(ZoneList<Expression*>* args) = 0;
-  virtual void GenerateTailCallWithArguments(ZoneList<Expression*>* args) = 0;
-  virtual void GenerateSetArgument(ZoneList<Expression*>* args) = 0;
-  virtual void GenerateSquashFrame(ZoneList<Expression*>* args) = 0;
-  virtual void GenerateExpandFrame(ZoneList<Expression*>* args) = 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;
diff --git a/src/compilation-cache.cc b/src/compilation-cache.cc
new file mode 100644
index 0000000..48b2870
--- /dev/null
+++ b/src/compilation-cache.cc
@@ -0,0 +1,157 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "compilation-cache.h"
+
+namespace v8 { namespace internal {
+
+enum {
+  NUMBER_OF_ENTRY_KINDS = CompilationCache::EVAL_CONTEXTUAL + 1
+};
+
+
+// Keep separate tables for the different entry kinds.
+static Object* tables[NUMBER_OF_ENTRY_KINDS] = { 0, };
+
+
+static Handle<CompilationCacheTable> AllocateTable(int size) {
+  CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size),
+                     CompilationCacheTable);
+}
+
+
+static Handle<CompilationCacheTable> GetTable(CompilationCache::Entry entry) {
+  Handle<CompilationCacheTable> result;
+  if (tables[entry]->IsUndefined()) {
+    static const int kInitialCacheSize = 64;
+    result = AllocateTable(kInitialCacheSize);
+    tables[entry] = *result;
+  } else {
+    CompilationCacheTable* table = CompilationCacheTable::cast(tables[entry]);
+    result = Handle<CompilationCacheTable>(table);
+  }
+  return result;
+}
+
+
+// We only re-use a cached function for some script source code if the
+// script originates from the same places. This is to avoid issues
+// when reporting errors, etc.
+static bool HasOrigin(Handle<JSFunction> boilerplate,
+                      Handle<Object> name,
+                      int line_offset,
+                      int column_offset) {
+  Handle<Script> script =
+      Handle<Script>(Script::cast(boilerplate->shared()->script()));
+  // If the script name isn't set, the boilerplate script should have
+  // an undefined name to have the same origin.
+  if (name.is_null()) {
+    return script->name()->IsUndefined();
+  }
+  // Do the fast bailout checks first.
+  if (line_offset != script->line_offset()->value()) return false;
+  if (column_offset != script->column_offset()->value()) return false;
+  // Check that both names are strings. If not, no match.
+  if (!name->IsString() || !script->name()->IsString()) return false;
+  // Compare the two name strings for equality.
+  return String::cast(*name)->Equals(String::cast(script->name()));
+}
+
+
+static Handle<JSFunction> Lookup(Handle<String> source,
+                                 CompilationCache::Entry entry) {
+  // Make sure not to leak the table into the surrounding handle
+  // scope. Otherwise, we risk keeping old tables around even after
+  // having cleared the cache.
+  Object* result;
+  { HandleScope scope;
+    Handle<CompilationCacheTable> table = GetTable(entry);
+    result = table->Lookup(*source);
+  }
+  if (result->IsJSFunction()) {
+    return Handle<JSFunction>(JSFunction::cast(result));
+  } else {
+    return Handle<JSFunction>::null();
+  }
+}
+
+
+Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source,
+                                                  Handle<Object> name,
+                                                  int line_offset,
+                                                  int column_offset) {
+  Handle<JSFunction> result = Lookup(source, SCRIPT);
+  if (result.is_null()) {
+    Counters::compilation_cache_misses.Increment();
+  } else if (HasOrigin(result, name, line_offset, column_offset)) {
+    Counters::compilation_cache_hits.Increment();
+  } else {
+    result = Handle<JSFunction>::null();
+    Counters::compilation_cache_misses.Increment();
+  }
+  return result;
+}
+
+
+Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source,
+                                                Entry entry) {
+  ASSERT(entry == EVAL_GLOBAL || entry == EVAL_CONTEXTUAL);
+  Handle<JSFunction> result = Lookup(source, entry);
+  if (result.is_null()) {
+    Counters::compilation_cache_misses.Increment();
+  } else {
+    Counters::compilation_cache_hits.Increment();
+  }
+  return result;
+}
+
+
+void CompilationCache::Associate(Handle<String> source,
+                                 Entry entry,
+                                 Handle<JSFunction> boilerplate) {
+  HandleScope scope;
+  ASSERT(boilerplate->IsBoilerplate());
+  Handle<CompilationCacheTable> table = GetTable(entry);
+  CALL_HEAP_FUNCTION_VOID(table->Put(*source, *boilerplate));
+}
+
+
+void CompilationCache::Clear() {
+  for (int i = 0; i < NUMBER_OF_ENTRY_KINDS; i++) {
+    tables[i] = Heap::undefined_value();
+  }
+}
+
+
+void CompilationCache::Iterate(ObjectVisitor* v) {
+  v->VisitPointers(&tables[0], &tables[NUMBER_OF_ENTRY_KINDS]);
+}
+
+
+} }  // namespace v8::internal
diff --git a/src/compilation-cache.h b/src/compilation-cache.h
new file mode 100644
index 0000000..a87c495
--- /dev/null
+++ b/src/compilation-cache.h
@@ -0,0 +1,85 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_COMPILATION_CACHE_H_
+#define V8_COMPILATION_CACHE_H_
+
+namespace v8 { namespace internal {
+
+
+// The compilation cache keeps function boilerplates for compiled
+// scripts and evals. The boilerplates are looked up using the source
+// string as the key.
+class CompilationCache {
+ public:
+  // The same source code string has different compiled code for
+  // scripts and evals. Internally, we use separate caches to avoid
+  // getting the wrong kind of entry when looking up.
+  enum Entry {
+    SCRIPT,
+    EVAL_GLOBAL,
+    EVAL_CONTEXTUAL
+  };
+
+  // Finds the script function boilerplate for a source
+  // string. Returns an empty handle if the cache doesn't contain a
+  // script for the given source string with the right origin.
+  static Handle<JSFunction> LookupScript(Handle<String> source,
+                                         Handle<Object> name,
+                                         int line_offset,
+                                         int column_offset);
+
+  // Finds the function boilerplate for a source string for
+  // eval. Returns an empty handle if the cache doesn't contain a
+  // script for the given source string.
+  static Handle<JSFunction> LookupEval(Handle<String> source,
+                                       Entry entry);
+
+  // Associate the (source, kind) pair to the boilerplate. This may
+  // overwrite an existing mapping.
+  static void Associate(Handle<String> source,
+                        Entry entry,
+                        Handle<JSFunction> boilerplate);
+
+  // Clear the cache - also used to initialize the cache at startup.
+  static void Clear();
+
+  // GC support.
+  static void Iterate(ObjectVisitor* v);
+
+  // Notify the cache that a mark-sweep garbage collection is about to
+  // take place. This is used to retire entries from the cache to
+  // avoid keeping them alive too long without using them. For now, we
+  // just clear the cache but we should consider are more
+  // sophisticated LRU scheme.
+  static void MarkCompactPrologue() { Clear(); }
+};
+
+
+} }  // namespace v8::internal
+
+#endif  // V8_COMPILATION_CACHE_H_
diff --git a/src/compiler.cc b/src/compiler.cc
index 78772a1..4a6d4a4 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -29,6 +29,7 @@
 
 #include "bootstrapper.h"
 #include "codegen-inl.h"
+#include "compilation-cache.h"
 #include "compiler.h"
 #include "debug.h"
 #include "scopes.h"
@@ -37,17 +38,6 @@
 
 namespace v8 { namespace internal {
 
-DEFINE_bool(strict, false, "strict error checking");
-DEFINE_int(min_preparse_length, 1024,
-           "Minimum length for automatic enable preparsing");
-DECLARE_bool(debug_info);
-
-#ifdef DEBUG
-DEFINE_bool(print_builtin_scopes, false, "print scopes for builtins");
-DEFINE_bool(print_scopes, false, "print scopes");
-#endif
-
-
 static Handle<Code> MakeCode(FunctionLiteral* literal,
                              Handle<Script> script,
                              bool is_eval) {
@@ -170,27 +160,44 @@
   // The VM is in the COMPILER state until exiting this function.
   VMState state(COMPILER);
 
-  ScriptDataImpl* pre_data = input_pre_data;
-  if (pre_data == NULL && source->length() >= FLAG_min_preparse_length) {
-    Access<SafeStringInputBuffer> buf(&safe_string_input_buffer);
-    buf->Reset(source.location());
-    pre_data = PreParse(buf.value(), extension);
+  // Do a lookup in the compilation cache but not for extensions.
+  Handle<JSFunction> result;
+  if (extension == NULL) {
+    result = CompilationCache::LookupScript(source,
+                                            script_name,
+                                            line_offset,
+                                            column_offset);
   }
 
-  // Create a script object describing the script to be compiled.
-  Handle<Script> script = Factory::NewScript(source);
-  if (!script_name.is_null()) {
-    script->set_name(*script_name);
-    script->set_line_offset(Smi::FromInt(line_offset));
-    script->set_column_offset(Smi::FromInt(column_offset));
+  if (result.is_null()) {
+    // No cache entry found. Do pre-parsing and compile the script.
+    ScriptDataImpl* pre_data = input_pre_data;
+    if (pre_data == NULL && source->length() >= FLAG_min_preparse_length) {
+      Access<SafeStringInputBuffer> buf(&safe_string_input_buffer);
+      buf->Reset(source.location());
+      pre_data = PreParse(buf.value(), extension);
+    }
+
+    // Create a script object describing the script to be compiled.
+    Handle<Script> script = Factory::NewScript(source);
+    if (!script_name.is_null()) {
+      script->set_name(*script_name);
+      script->set_line_offset(Smi::FromInt(line_offset));
+      script->set_column_offset(Smi::FromInt(column_offset));
+    }
+
+    // Compile the function and add it to the cache.
+    result = MakeFunction(true, false, script, extension, pre_data);
+    if (extension == NULL && !result.is_null()) {
+      CompilationCache::Associate(source, CompilationCache::SCRIPT, result);
+    }
+
+    // Get rid of the pre-parsing data (if necessary).
+    if (input_pre_data == NULL && pre_data != NULL) {
+      delete pre_data;
+    }
   }
 
-  Handle<JSFunction> result =
-      MakeFunction(true, false, script, extension, pre_data);
-
-  if (input_pre_data == NULL && pre_data != NULL)
-    delete pre_data;
-
   return result;
 }
 
@@ -202,10 +209,22 @@
 
   // The VM is in the COMPILER state until exiting this function.
   VMState state(COMPILER);
+  CompilationCache::Entry entry = is_global
+      ? CompilationCache::EVAL_GLOBAL
+      : CompilationCache::EVAL_CONTEXTUAL;
 
-  // Create a script object describing the script to be compiled.
-  Handle<Script> script = Factory::NewScript(source);
-  return MakeFunction(is_global, true, script, NULL, NULL);
+  // Do a lookup in the compilation cache; if the entry is not there,
+  // invoke the compiler and add the result to the cache.
+  Handle<JSFunction> result = CompilationCache::LookupEval(source, entry);
+  if (result.is_null()) {
+    // Create a script object describing the script to be compiled.
+    Handle<Script> script = Factory::NewScript(source);
+    result = MakeFunction(is_global, true, script, NULL, NULL);
+    if (!result.is_null()) {
+      CompilationCache::Associate(source, entry, result);
+    }
+  }
+  return result;
 }
 
 
diff --git a/src/contexts.cc b/src/contexts.cc
index 2142fac..e987b45 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -32,14 +32,6 @@
 
 namespace v8 { namespace internal {
 
-
-#ifdef DEBUG
-DEFINE_bool(trace_contexts, false, "trace contexts operations");
-#else
-#define FLAG_trace_contexts false
-#endif
-
-
 JSBuiltinsObject* Context::builtins() {
   GlobalObject* object = global();
   if (object->IsJSGlobalObject()) {
diff --git a/src/conversions.cc b/src/conversions.cc
index 85637ee..a1adb22 100644
--- a/src/conversions.cc
+++ b/src/conversions.cc
@@ -269,18 +269,27 @@
   // Skip leading spaces.
   while ((index < len) && IsSpace(str, index)) index++;
 
-  // Compute sign of result.
+  // Is the string empty?
+  if (index >= len) return empty_string_val;
+
+  // Get the first character.
+  uint16_t first = GetChar(str, index);
+
+  // Numbers can only start with '-', '+', '.', 'I' (Infinity), or a digit.
+  if (first != '-' && first != '+' && first != '.' && first != 'I' &&
+      (first > '9' || first < '0')) {
+    return JUNK_STRING_VALUE;
+  }
+
+  // Compute sign of result based on first character.
   int sign = 1;
-  if (index < len && GetChar(str, index) == '-') {
+  if (first == '-') {
     sign = -1;
     index++;
     // String only containing a '-' are junk chars.
     if (index == len) return JUNK_STRING_VALUE;
   }
 
-  // string is empty?
-  if (index >= len) return empty_string_val;
-
   // do we have a hex number?
   // (since the string is 0-terminated, it's ok to look one char beyond the end)
   if ((flags & ALLOW_HEX) != 0 &&
diff --git a/src/counters.cc b/src/counters.cc
index 3baad29..8878ec5 100644
--- a/src/counters.cc
+++ b/src/counters.cc
@@ -34,19 +34,9 @@
 
 CounterLookupCallback StatsTable::lookup_function_ = NULL;
 
-StatsCounterTimer::StatsCounterTimer(const wchar_t* name)
-  : start_time_(0),  // initialize to avoid compiler complaints
-    stop_time_(0) {  // initialize to avoid compiler complaints
-  int len = wcslen(name);
-  // we prepend the name with 'c.' to indicate that it is a counter.
-  name_ = NewArray<wchar_t>(len+3);
-  wcscpy(name_, L"t:");
-  wcscpy(&name_[2], name);
-}
-
 // Start the timer.
 void StatsCounterTimer::Start() {
-  if (!Enabled())
+  if (!counter_.Enabled())
     return;
   stop_time_ = 0;
   start_time_ = OS::Ticks();
@@ -54,10 +44,13 @@
 
 // Stop the timer and record the results.
 void StatsCounterTimer::Stop() {
-  if (!Enabled())
+  if (!counter_.Enabled())
     return;
   stop_time_ = OS::Ticks();
-  Record();
+
+  // Compute the delta between start and stop, in milliseconds.
+  int milliseconds = static_cast<int>(stop_time_ - start_time_) / 1000;
+  counter_.Increment(milliseconds);
 }
 
 } }  // namespace v8::internal
diff --git a/src/counters.h b/src/counters.h
index 6dd9e94..270c091 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -67,38 +67,18 @@
 // the StatsTable.  They are designed to be lightweight to create and
 // easy to use.
 //
-// The implementation of the StatsTable is external to this module.
-//
-// Example usage:
-//    {
-//      StatsCounter request_count("RequestCount");
-//      request_count.Increment();
-//    }
-//
 // Internally, a counter represents a value in a row of a StatsTable.
 // The row has a 32bit value for each process/thread in the table and also
 // a name (stored in the table metadata).  Since the storage location can be
 // thread-specific, this class cannot be shared across threads.
 //
-
-// StatsCounter represents a counter in the StatsTable class.
-class StatsCounter BASE_EMBEDDED {
- public:
-  // Create a StatsCounter object.
-  explicit StatsCounter(const wchar_t* name, int id) :
-      lookup_done_(false),
-      ptr_(NULL),
-      id_(id) {
-    int len = wcslen(name);
-    // we prepend the name with 'c:' to indicate that it is a counter.
-    name_ = NewArray<wchar_t>(len+3);
-    wcscpy(name_, L"c:");
-    wcscpy(&name_[2], name);
-  };
-
-  ~StatsCounter() {
-    DeleteArray(name_);
-  }
+// This class is designed to be POD initialized.  It will be registered with
+// the counter system on first use.  For example:
+//   StatsCounter c = { L"c:myctr", NULL, false };
+struct StatsCounter {
+  const wchar_t* name_;
+  int* ptr_;
+  bool lookup_done_;
 
   // Sets the counter to a specific value.
   void Set(int value) {
@@ -144,16 +124,7 @@
     return loc;
   }
 
-  int Id() {
-    return id_;
-  }
-
  protected:
-  StatsCounter() :
-      lookup_done_(false),
-      ptr_(NULL) {
-  }
-
   // Returns the cached address of this counter location.
   int* GetPtr() {
     if (lookup_done_)
@@ -162,20 +133,14 @@
     ptr_ = StatsTable::FindLocation(name_);
     return ptr_;
   }
-
-  wchar_t* name_;
-  bool lookup_done_;
-  int* ptr_;
-  int id_;
 };
 
-// A StatsCounterTimer is a StatsCounter which keeps a timer during
-// the scope of the StatsCounterTimer.  On destruction, it will record
-// its time measurement.
-class StatsCounterTimer : StatsCounter {
- public:
-  // Constructs and starts the timer.
-  explicit StatsCounterTimer(const wchar_t* name);
+// StatsCounterTimer t = { { L"t:foo", NULL, false }, 0, 0 };
+struct StatsCounterTimer {
+  StatsCounter counter_;
+
+  int64_t start_time_;
+  int64_t stop_time_;
 
   // Start the timer.
   void Start();
@@ -185,31 +150,20 @@
 
   // Returns true if the timer is running.
   bool Running() {
-    return Enabled() && start_time_ != 0 && stop_time_ == 0;
+    return counter_.Enabled() && start_time_ != 0 && stop_time_ == 0;
   }
-
- private:
-  // Compute the delta between start and stop, in milliseconds.
-  void Record() {
-    int milliseconds = static_cast<int>(stop_time_ - start_time_) / 1000;
-    Increment(milliseconds);
-  }
-
-  int64_t start_time_;
-  int64_t stop_time_;
 };
 
-
 // A StatsRate is a combination of both a timer and a counter so that
 // several statistics can be produced:
 //    min, max, avg, count, total
-class StatsRate BASE_EMBEDDED {
- public:
-  // Constructs and starts the timer.
-  explicit StatsRate(const wchar_t* name, int id) :
-      timer_(name),
-      counter_(name, id) {
-  }
+//
+// For example:
+//   StatsCounter c = { { { L"t:myrate", NULL, false }, 0, 0 },
+//                      { L"c:myrate", NULL, false } };
+struct StatsRate {
+  StatsCounterTimer timer_;
+  StatsCounter counter_;
 
   // Starts the rate timer.
   void Start() {
@@ -223,30 +177,9 @@
       counter_.Increment();
     }
   }
-
-  // Access to the timer.
-  StatsCounterTimer& timer() { return timer_; }
-
- private:
-  StatsCounterTimer timer_;
-  StatsCounter counter_;
 };
 
 
-// Helper class for scoping a timer.
-class StatsTimerScope BASE_EMBEDDED {
- public:
-  explicit StatsTimerScope(StatsCounterTimer* timer) :
-      timer_(timer) {
-    timer_->Start();
-  }
-  ~StatsTimerScope() {
-    timer_->Stop();
-  }
- private:
-  StatsCounterTimer* timer_;
-};
-
 // Helper class for scoping a rate.
 class StatsRateScope BASE_EMBEDDED {
  public:
diff --git a/src/debug.cc b/src/debug.cc
index f69b6b7..3fc7545 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -41,12 +41,6 @@
 
 namespace v8 { namespace internal {
 
-DEFINE_bool(remote_debugging, false, "enable remote debugging");
-DEFINE_bool(trace_debug_json, false, "trace debugging JSON request/response");
-DECLARE_bool(allow_natives_syntax);
-DECLARE_bool(log_debugger);
-
-
 static void PrintLn(v8::Local<v8::Value> value) {
   v8::Local<v8::String> s = value->ToString();
   char* data = NewArray<char>(s->Length() + 1);
diff --git a/src/disasm-arm.cc b/src/disasm-arm.cc
index 0b69bdf..88f6842 100644
--- a/src/disasm-arm.cc
+++ b/src/disasm-arm.cc
@@ -52,12 +52,10 @@
 class Decoder {
  public:
   Decoder(const disasm::NameConverter& converter,
-          char* out_buffer, const int out_buffer_size)
+          v8::internal::Vector<char> out_buffer)
     : converter_(converter),
       out_buffer_(out_buffer),
-      out_buffer_size_(out_buffer_size),
       out_buffer_pos_(0) {
-    ASSERT(out_buffer_size_ > 0);
     out_buffer_[out_buffer_pos_] = '\0';
   }
 
@@ -69,8 +67,7 @@
 
  private:
   const disasm::NameConverter& converter_;
-  char* out_buffer_;
-  const int out_buffer_size_;
+  v8::internal::Vector<char> out_buffer_;
   int out_buffer_pos_;
 
   void PrintChar(const char ch);
@@ -98,7 +95,6 @@
 
 // Append the ch to the output buffer.
 void Decoder::PrintChar(const char ch) {
-  ASSERT(out_buffer_pos_ < out_buffer_size_);
   out_buffer_[out_buffer_pos_++] = ch;
 }
 
@@ -106,7 +102,7 @@
 // Append the str to the output buffer.
 void Decoder::Print(const char* str) {
   char cur = *str++;
-  while (cur != 0 && (out_buffer_pos_ < (out_buffer_size_-1))) {
+  while (cur != 0 && (out_buffer_pos_ < (out_buffer_.length()-1))) {
     PrintChar(cur);
     cur = *str++;
   }
@@ -159,14 +155,12 @@
       shift_amount = 32;
     }
     out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
-                                         out_buffer_size_ - out_buffer_pos_,
                                          ", %s #%d",
                                          shift_names[shift], shift_amount);
   } else {
     // by register
     int rs = instr->RsField();
     out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
-                                         out_buffer_size_ - out_buffer_pos_,
                                          ", %s ", shift_names[shift]);
     PrintRegister(rs);
   }
@@ -180,7 +174,6 @@
   int immed8 = instr->Immed8Field();
   int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
   out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
-                                       out_buffer_size_ - out_buffer_pos_,
                                        "#%d", imm);
 }
 
@@ -250,7 +243,6 @@
         byte* str =
             reinterpret_cast<byte*>(instr->InstructionBits() & 0x0fffffff);
         out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
-                                             out_buffer_size_ - out_buffer_pos_,
                                              "%s", converter_.NameInCode(str));
         return 3;
       }
@@ -262,7 +254,6 @@
         // 'off12: 12-bit offset for load and store instructions
         ASSERT(format[4] == '2');
         out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
-                                             out_buffer_size_ - out_buffer_pos_,
                                              "%d", instr->Offset12Field());
         return 5;
       } else {
@@ -270,7 +261,6 @@
         ASSERT(format[3] == '8');
         int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField();
         out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
-                                             out_buffer_size_ - out_buffer_pos_,
                                              "%d", offs8);
         return 4;
       }
@@ -367,7 +357,6 @@
           default:
             out_buffer_pos_ += v8i::OS::SNPrintF(
                 out_buffer_ + out_buffer_pos_,
-                out_buffer_size_ - out_buffer_pos_,
                 "%d",
                 swi);
             break;
@@ -394,7 +383,6 @@
       int off = (instr->SImmed24Field() << 2) + 8;
       out_buffer_pos_ += v8i::OS::SNPrintF(
           out_buffer_ + out_buffer_pos_,
-          out_buffer_size_ - out_buffer_pos_,
           "%+d -> %s",
           off,
           converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
@@ -432,7 +420,7 @@
 // parsed further.
 void Decoder::Format(Instr* instr, const char* format) {
   char cur = *format++;
-  while ((cur != 0) && (out_buffer_pos_ < (out_buffer_size_ - 1))) {
+  while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
     if (cur == '\'') {  // Single quote is used as the formatting escape.
       format += FormatOption(instr, format);
     } else {
@@ -440,7 +428,6 @@
     }
     cur = *format++;
   }
-  ASSERT(out_buffer_pos_ < out_buffer_size_);
   out_buffer_[out_buffer_pos_]  = '\0';
 }
 
@@ -804,7 +791,6 @@
   Instr* instr = Instr::At(instr_ptr);
   // Print raw instruction bytes.
   out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
-                                       out_buffer_size_ - out_buffer_pos_,
                                        "%08x       ",
                                        instr->InstructionBits());
   if (instr->ConditionField() == special_condition) {
@@ -922,9 +908,9 @@
 Disassembler::~Disassembler() {}
 
 
-int Disassembler::InstructionDecode(char* buffer, const int buffer_size,
+int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
                                     byte* instruction) {
-  assembler::arm::Decoder d(converter_, buffer, buffer_size);
+  assembler::arm::Decoder d(converter_, buffer);
   return d.InstructionDecode(instruction);
 }
 
@@ -942,12 +928,12 @@
 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
   Disassembler d;
   for (byte* pc = begin; pc < end;) {
-    char buffer[128];
+    v8::internal::EmbeddedVector<char, 128> buffer;
     buffer[0] = '\0';
     byte* prev_pc = pc;
-    pc += d.InstructionDecode(buffer, sizeof buffer, pc);
+    pc += d.InstructionDecode(buffer, pc);
     fprintf(f, "%p    %08x      %s\n",
-            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
+            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
   }
 }
 
diff --git a/src/disasm-ia32.cc b/src/disasm-ia32.cc
index ac12e1f..1648d69 100644
--- a/src/disasm-ia32.cc
+++ b/src/disasm-ia32.cc
@@ -233,11 +233,11 @@
 
   // Writes one disassembled instruction into 'buffer' (0-terminated).
   // Returns the length of the disassembled machine instruction in bytes.
-  int InstructionDecode(char* buffer, const int buffer_size, byte* instruction);
+  int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction);
 
  private:
   const NameConverter& converter_;
-  char tmp_buffer_[128];
+  v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
   unsigned int tmp_buffer_pos_;
   bool abort_on_unimplemented_;
 
@@ -307,15 +307,10 @@
 
 
 void DisassemblerIA32::AppendToBuffer(const char* format, ...) {
-  char* str = tmp_buffer_ + tmp_buffer_pos_;
-  int size = (sizeof tmp_buffer_) - tmp_buffer_pos_;
+  v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_;
   va_list args;
   va_start(args, format);
-#ifdef WIN32
-  int result = _vsnprintf(str, size, format, args);
-#else
-  int result = vsnprintf(str, size, format, args);
-#endif
+  int result = v8::internal::OS::VSNPrintF(buf, format, args);
   va_end(args);
   tmp_buffer_pos_ += result;
 }
@@ -706,8 +701,7 @@
 
 
 // Disassembled instruction '*instr' and writes it intro 'out_buffer'.
-int DisassemblerIA32::InstructionDecode(char* out_buffer,
-                                        const int out_buffer_size,
+int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
                                         byte* instr) {
   tmp_buffer_pos_ = 0;  // starting to write as position 0
   byte* data = instr;
@@ -1040,20 +1034,17 @@
   // Instruction bytes.
   for (byte* bp = instr; bp < data; bp++) {
     outp += v8::internal::OS::SNPrintF(out_buffer + outp,
-                                       out_buffer_size - outp,
                                        "%02x",
                                        *bp);
   }
   for (int i = 6 - instr_len; i >= 0; i--) {
     outp += v8::internal::OS::SNPrintF(out_buffer + outp,
-                                       out_buffer_size - outp,
                                        "  ");
   }
 
   outp += v8::internal::OS::SNPrintF(out_buffer + outp,
-                                     out_buffer_size - outp,
                                      " %s",
-                                     tmp_buffer_);
+                                     tmp_buffer_.start());
   return instr_len;
 }
 
@@ -1072,13 +1063,9 @@
 
 
 const char* NameConverter::NameOfAddress(byte* addr) const {
-  static char tmp_buffer[32];
-#ifdef WIN32
-  _snprintf(tmp_buffer, sizeof tmp_buffer, "%p", addr);
-#else
-  snprintf(tmp_buffer, sizeof tmp_buffer, "%p", addr);
-#endif
-  return tmp_buffer;
+  static v8::internal::EmbeddedVector<char, 32> tmp_buffer;
+  v8::internal::OS::SNPrintF(tmp_buffer, "%p", addr);
+  return tmp_buffer.start();
 }
 
 
@@ -1120,11 +1107,10 @@
 Disassembler::~Disassembler() {}
 
 
-int Disassembler::InstructionDecode(char* buffer,
-                                    const int buffer_size,
+int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
                                     byte* instruction) {
   DisassemblerIA32 d(converter_, false /*do not crash if unimplemented*/);
-  return d.InstructionDecode(buffer, buffer_size, instruction);
+  return d.InstructionDecode(buffer, instruction);
 }
 
 
@@ -1135,10 +1121,10 @@
 /*static*/ void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
   Disassembler d;
   for (byte* pc = begin; pc < end;) {
-    char buffer[128];
+    v8::internal::EmbeddedVector<char, 128> buffer;
     buffer[0] = '\0';
     byte* prev_pc = pc;
-    pc += d.InstructionDecode(buffer, sizeof buffer, pc);
+    pc += d.InstructionDecode(buffer, pc);
     fprintf(f, "%p", prev_pc);
     fprintf(f, "    ");
 
@@ -1148,7 +1134,7 @@
     for (int i = 6 - (pc - prev_pc); i >= 0; i--) {
       fprintf(f, "  ");
     }
-    fprintf(f, "  %s\n", buffer);
+    fprintf(f, "  %s\n", buffer.start());
   }
 }
 
diff --git a/src/disasm.h b/src/disasm.h
index f590b28..1b72ee1 100644
--- a/src/disasm.h
+++ b/src/disasm.h
@@ -59,7 +59,7 @@
 
   // Writes one disassembled instruction into 'buffer' (0-terminated).
   // Returns the length of the disassembled machine instruction in bytes.
-  int InstructionDecode(char* buffer, const int buffer_size, byte* instruction);
+  int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction);
 
   // Returns -1 if instruction does not mark the beginning of a constant pool,
   // or the number of entries in the constant pool beginning here.
diff --git a/src/disassembler.cc b/src/disassembler.cc
index 635440d..5d3412a 100644
--- a/src/disassembler.cc
+++ b/src/disassembler.cc
@@ -63,20 +63,20 @@
 
 
 const char* V8NameConverter::NameOfAddress(byte* pc) const {
-  static char buffer[128];
+  static v8::internal::EmbeddedVector<char, 128> buffer;
 
   const char* name = Builtins::Lookup(pc);
   if (name != NULL) {
-    OS::SNPrintF(buffer, sizeof buffer, "%s  (%p)", name, pc);
-    return buffer;
+    OS::SNPrintF(buffer, "%s  (%p)", name, pc);
+    return buffer.start();
   }
 
   if (code_ != NULL) {
     int offs = pc - code_->instruction_start();
     // print as code offset, if it seems reasonable
     if (0 <= offs && offs < code_->instruction_size()) {
-      OS::SNPrintF(buffer, sizeof buffer, "%d  (%p)", offs, pc);
-      return buffer;
+      OS::SNPrintF(buffer, "%d  (%p)", offs, pc);
+      return buffer.start();
     }
   }
 
@@ -110,8 +110,8 @@
   AssertNoAllocation no_alloc;
   ExternalReferenceEncoder ref_encoder;
 
-  char decode_buffer[128];
-  char out_buffer[kOutBufferSize];
+  v8::internal::EmbeddedVector<char, 128> decode_buffer;
+  v8::internal::EmbeddedVector<char, kOutBufferSize> out_buffer;
   byte* pc = begin;
   disasm::Disassembler d(converter);
   RelocIterator* it = NULL;
@@ -127,7 +127,6 @@
     byte* prev_pc = pc;
     if (constants > 0) {
       OS::SNPrintF(decode_buffer,
-                   sizeof(decode_buffer),
                    "%08x       constant",
                    *reinterpret_cast<int32_t*>(pc));
       constants--;
@@ -136,14 +135,13 @@
       int num_const = d.ConstantPoolSizeAt(pc);
       if (num_const >= 0) {
         OS::SNPrintF(decode_buffer,
-                     sizeof(decode_buffer),
                      "%08x       constant pool begin",
                      *reinterpret_cast<int32_t*>(pc));
         constants = num_const;
         pc += 4;
       } else {
         decode_buffer[0] = '\0';
-        pc += d.InstructionDecode(decode_buffer, sizeof decode_buffer, pc);
+        pc += d.InstructionDecode(decode_buffer, pc);
       }
     }
 
@@ -167,7 +165,7 @@
       }
     }
 
-    StringBuilder out(out_buffer, sizeof(out_buffer));
+    StringBuilder out(out_buffer.start(), out_buffer.length());
 
     // Comments.
     for (int i = 0; i < comments.length(); i++) {
@@ -182,7 +180,7 @@
     out.AddFormatted("%p  %4d  ", prev_pc, prev_pc - begin);
 
     // Instruction.
-    out.AddFormatted("%s", decode_buffer);
+    out.AddFormatted("%s", decode_buffer.start());
 
     // Print all the reloc info for this instruction which are not comments.
     for (int i = 0; i < pcs.length(); i++) {
@@ -199,55 +197,72 @@
         out.AddPadding(' ', kRelocInfoPosition);
       }
 
-      if (is_position(relocinfo.rmode())) {
-        out.AddFormatted("    ;; debug: statement %d", relocinfo.data());
-      } else if (relocinfo.rmode() == embedded_object) {
+      RelocMode rmode = relocinfo.rmode();
+      if (is_position(rmode)) {
+        if (is_statement_position(rmode)) {
+          out.AddFormatted("    ;; debug: statement %d", relocinfo.data());
+        } else {
+          out.AddFormatted("    ;; debug: position %d", relocinfo.data());
+        }
+      } else if (rmode == embedded_object) {
         HeapStringAllocator allocator;
         StringStream accumulator(&allocator);
         relocinfo.target_object()->ShortPrint(&accumulator);
         SmartPointer<char> obj_name = accumulator.ToCString();
         out.AddFormatted("    ;; object: %s", *obj_name);
-      } else if (relocinfo.rmode() == external_reference) {
+      } else if (rmode == external_reference) {
         const char* reference_name =
             ref_encoder.NameOfAddress(*relocinfo.target_reference_address());
         out.AddFormatted("    ;; external reference (%s)", reference_name);
-      } else {
-        out.AddFormatted("    ;; %s",
-                         RelocInfo::RelocModeName(relocinfo.rmode()));
-        if (is_code_target(relocinfo.rmode())) {
-          Code* code = Debug::GetCodeTarget(relocinfo.target_address());
-          Code::Kind kind = code->kind();
-          if (kind == Code::STUB) {
-            // Reverse lookup required as the minor key cannot be retrieved
-            // from the code object.
-            Object* obj = Heap::code_stubs()->SlowReverseLookup(code);
-            if (obj != Heap::undefined_value()) {
-              ASSERT(obj->IsSmi());
-              // Get the STUB key and extract major and minor key.
-              uint32_t key = Smi::cast(obj)->value();
-              uint32_t minor_key = CodeStub::MinorKeyFromKey(key);
-              ASSERT(code->major_key() == CodeStub::MajorKeyFromKey(key));
-              out.AddFormatted(" (%s, %s, ",
-                               Code::Kind2String(kind),
-                               CodeStub::MajorName(code->major_key()));
-              switch (code->major_key()) {
-                case CodeStub::CallFunction:
-                  out.AddFormatted("argc = %d)", minor_key);
-                  break;
-                case CodeStub::Runtime: {
-                  const char* name =
-                      RuntimeStub::GetNameFromMinorKey(minor_key);
-                  out.AddFormatted("%s)", name);
-                  break;
-                }
-                default:
-                  out.AddFormatted("minor: %d)", minor_key);
-              }
-            }
-          } else {
-            out.AddFormatted(" (%s)", Code::Kind2String(kind));
-          }
+      } else if (is_code_target(rmode)) {
+        out.AddFormatted("    ;; code:");
+        if (rmode == js_construct_call) {
+          out.AddFormatted(" constructor,");
         }
+        Code* code = Debug::GetCodeTarget(relocinfo.target_address());
+        Code::Kind kind = code->kind();
+        if (code->is_inline_cache_stub()) {
+          if (rmode == code_target_context) {
+            out.AddFormatted(" contextual,");
+          }
+          InlineCacheState ic_state = code->ic_state();
+          out.AddFormatted(" %s, %s", Code::Kind2String(kind),
+              Code::ICState2String(ic_state));
+          if (kind == Code::CALL_IC) {
+            out.AddFormatted(", argc = %d", code->arguments_count());
+          }
+        } else if (kind == Code::STUB) {
+          // Reverse lookup required as the minor key cannot be retrieved
+          // from the code object.
+          Object* obj = Heap::code_stubs()->SlowReverseLookup(code);
+          if (obj != Heap::undefined_value()) {
+            ASSERT(obj->IsSmi());
+            // Get the STUB key and extract major and minor key.
+            uint32_t key = Smi::cast(obj)->value();
+            uint32_t minor_key = CodeStub::MinorKeyFromKey(key);
+            ASSERT(code->major_key() == CodeStub::MajorKeyFromKey(key));
+            out.AddFormatted(" %s, %s, ",
+                             Code::Kind2String(kind),
+                             CodeStub::MajorName(code->major_key()));
+            switch (code->major_key()) {
+              case CodeStub::CallFunction:
+                out.AddFormatted("argc = %d", minor_key);
+                break;
+              case CodeStub::Runtime: {
+                const char* name =
+                    RuntimeStub::GetNameFromMinorKey(minor_key);
+                out.AddFormatted("%s", name);
+                break;
+              }
+              default:
+                out.AddFormatted("minor: %d", minor_key);
+            }
+          }
+        } else {
+          out.AddFormatted(" %s", Code::Kind2String(kind));
+        }
+      } else {
+        out.AddFormatted("    ;; %s", RelocInfo::RelocModeName(rmode));
       }
     }
     out.AddString("\n");
diff --git a/src/execution.cc b/src/execution.cc
index ce2259e..3213a34 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -154,8 +154,6 @@
 }
 
 
-DEFINE_bool(call_regexp, false, "allow calls to RegExp objects");
-
 Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
   ASSERT(!object->IsJSFunction());
 
@@ -587,10 +585,10 @@
     static const size_t kErrorPrefixLength = 25;  // strlen is not constant
     ASSERT(strlen(kErrorPrefix) == kErrorPrefixLength);
     static const int kMaxErrorLength = kMaxPathLength + kErrorPrefixLength;
-    char error_buffer[kMaxErrorLength + 1];
-    OS::SNPrintF(error_buffer, kMaxErrorLength, "%s%s",
-                 kErrorPrefix, file_name_buffer);
-    v8::Handle<v8::String> error = v8::String::New(error_buffer);
+    EmbeddedVector<char, kMaxErrorLength + 1> error_buffer;
+    OS::SNPrintF(error_buffer, "%s%s", kErrorPrefix, file_name_buffer);
+    v8::Handle<v8::String> error =
+        v8::String::New(error_buffer.start(), error_buffer.length());
     v8::ThrowException(v8::Exception::Error(error));
     return result;
   }
diff --git a/src/factory.cc b/src/factory.cc
index 9149cb8..444e7e2 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -727,6 +727,7 @@
   }
 
   result->shared()->set_function_data(*obj);
+  result->shared()->DontAdaptArguments();
 
   // Recursively copy parent templates' accessors, 'data' may be modified.
   Handle<DescriptorArray> array =
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
new file mode 100644
index 0000000..ac0aeb6
--- /dev/null
+++ b/src/flag-definitions.h
@@ -0,0 +1,318 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file defines all of the flags.  It is separated into different section,
+// for Debug, Release, Logging and Profiling, etc.  To add a new flag, find the
+// correct section, and use one of the DEFINE_ macros, without a trailing ';'.
+//
+// This include does not have a guard, because it is a template-style include,
+// which can be included multiple times in different modes.  It expects to have
+// a mode defined before it's included.  The modes are FLAG_MODE_... below:
+
+// We want to declare the names of the variables for the header file.  Normally
+// this will just be an extern declaration, but for a readonly flag we let the
+// compiler make better optimizations by giving it the value.
+#if defined(FLAG_MODE_DECLARE)
+#define FLAG_FULL(ftype, ctype, nam, def, cmt) \
+  extern ctype FLAG_##nam;
+#define FLAG_READONLY(ftype, ctype, nam, def, cmt) \
+  static ctype const FLAG_##nam = def;
+
+// We want to supply the actual storage and value for the flag variable in the
+// .cc file.  We only do this for writable flags.
+#elif defined(FLAG_MODE_DEFINE)
+#define FLAG_FULL(ftype, ctype, nam, def, cmt) \
+  ctype FLAG_##nam = def;
+#define FLAG_READONLY(ftype, ctype, nam, def, cmt)
+
+// We need to define all of our default values so that the Flag structure can
+// access them by pointer.  These are just used internally inside of one .cc,
+// for MODE_META, so there is no impact on the flags interface.
+#elif defined(FLAG_MODE_DEFINE_DEFAULTS)
+#define FLAG_FULL(ftype, ctype, nam, def, cmt) \
+  static ctype const FLAGDEFAULT_##nam = def;
+#define FLAG_READONLY(ftype, ctype, nam, def, cmt)
+
+
+// We want to write entries into our meta data table, for internal parsing and
+// printing / etc in the flag parser code.  We only do this for writable flags.
+#elif defined(FLAG_MODE_META)
+#define FLAG_FULL(ftype, ctype, nam, def, cmt) \
+  { Flag::TYPE_##ftype, #nam, &FLAG_##nam, &FLAGDEFAULT_##nam, cmt },
+#define FLAG_READONLY(ftype, ctype, nam, def, cmt)
+
+#else
+#error No mode supplied when including flags.defs
+#endif
+
+#define DEFINE_bool(nam, def, cmt) FLAG(BOOL, bool, nam, def, cmt)
+#define DEFINE_int(nam, def, cmt) FLAG(INT, int, nam, def, cmt)
+#define DEFINE_float(nam, def, cmt) FLAG(FLOAT, double, nam, def, cmt)
+#define DEFINE_string(nam, def, cmt) FLAG(STRING, const char*, nam, def, cmt)
+
+//
+// Flags in all modes.
+//
+#define FLAG FLAG_FULL
+
+// assembler-ia32.cc / assembler-arm.cc
+DEFINE_bool(debug_code, false,
+            "generate extra code (comments, assertions) for debugging")
+DEFINE_bool(emit_branch_hints, false, "emit branch hints")
+DEFINE_bool(push_pop_elimination, true,
+            "eliminate redundant push/pops in assembly code")
+DEFINE_bool(print_push_pop_elimination, false,
+            "print elimination of redundant push/pops in assembly code")
+DEFINE_bool(eliminate_jumps, true, "eliminate jumps to jumps in assembly code")
+DEFINE_bool(print_jump_elimination, false,
+            "print elimination of jumps to jumps in assembly code")
+
+// bootstrapper.cc
+DEFINE_string(expose_natives_as, NULL, "expose natives in global object")
+DEFINE_string(expose_debug_as, NULL, "expose debug in global object")
+DEFINE_string(natives_file, NULL, "alternative natives file")
+DEFINE_bool(expose_gc, false, "expose gc extension")
+
+// builtins-ia32.cc
+DEFINE_bool(inline_new, true, "use fast inline allocation")
+
+// checks.cc
+DEFINE_bool(stack_trace_on_abort, true,
+            "print a stack trace if an assertion failure occurs")
+
+// codegen-ia32.cc / codegen-arm.cc
+DEFINE_bool(trace, false, "trace function calls")
+DEFINE_bool(defer_negation, true, "defer negation operation")
+DEFINE_bool(check_stack, true,
+            "check stack for overflow, interrupt, breakpoint")
+
+// codegen.cc
+DEFINE_bool(lazy, true, "use lazy compilation")
+DEFINE_bool(debug_info, true, "add debug information to compiled functions")
+
+// compiler.cc
+DEFINE_bool(strict, false, "strict error checking")
+DEFINE_int(min_preparse_length, 1024,
+           "Minimum length for automatic enable preparsing")
+
+// debug.cc
+DEFINE_bool(remote_debugging, false, "enable remote debugging")
+DEFINE_bool(trace_debug_json, false, "trace debugging JSON request/response")
+
+// execution.cc
+DEFINE_bool(call_regexp, false, "allow calls to RegExp objects")
+
+// frames.cc
+DEFINE_int(max_stack_trace_source_length, 300,
+           "maximum length of function source code printed in a stack trace.")
+
+// heap.cc
+DEFINE_int(new_space_size, 0, "size of (each semispace in) the new generation")
+DEFINE_int(old_space_size, 0, "size of the old generation")
+DEFINE_bool(gc_global, false, "always perform global GCs")
+DEFINE_int(gc_interval, -1, "garbage collect after <n> allocations")
+DEFINE_bool(trace_gc, false,
+            "print one trace line following each garbage collection")
+
+// ic.cc
+DEFINE_bool(use_ic, true, "use inline caching")
+
+// macro-assembler-ia32.cc
+DEFINE_bool(native_code_counters, false,
+            "generate extra code for manipulating stats counters")
+
+// mark-compact.cc
+DEFINE_bool(always_compact, false, "Perform compaction on every full GC")
+DEFINE_bool(never_compact, false,
+            "Never perform compaction on full GC - testing only")
+DEFINE_bool(cleanup_ics_at_gc, true,
+            "Flush inline caches prior to mark compact collection.")
+DEFINE_bool(cleanup_caches_in_maps_at_gc, true,
+            "Flush code caches in maps during mark compact cycle.")
+
+// mksnapshot.cc
+DEFINE_bool(h, false, "print this message")
+
+// parser.cc
+DEFINE_bool(allow_natives_syntax, false, "allow natives syntax")
+
+// simulator-arm.cc
+DEFINE_bool(trace_sim, false, "trace simulator execution")
+DEFINE_int(stop_sim_at, 0, "Simulator stop after x number of instructions")
+
+// top.cc
+DEFINE_bool(trace_exception, false,
+            "print stack trace when throwing exceptions")
+DEFINE_bool(preallocate_message_memory, false,
+            "preallocate some memory to build stack traces.")
+
+// usage-analyzer.cc
+DEFINE_bool(usage_computation, true, "compute variable usage counts")
+
+// v8.cc
+DEFINE_bool(preemption, false,
+            "activate a 100ms timer that switches between V8 threads")
+
+// Testing flags test/cctest/test-{flags,api,serialization}.cc
+DEFINE_bool(testing_bool_flag, true, "testing_bool_flag")
+DEFINE_int(testing_int_flag, 13, "testing_int_flag")
+DEFINE_float(testing_float_flag, 2.5, "float-flag")
+DEFINE_string(testing_string_flag, "Hello, world!", "string-flag")
+DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness")
+#ifdef WIN32
+DEFINE_string(testing_serialization_file, "C:\\Windows\\Temp\\serdes",
+              "file in which to testing_serialize heap")
+#else
+DEFINE_string(testing_serialization_file, "/tmp/serdes",
+              "file in which to serialize heap")
+#endif
+
+
+
+//
+// Debug only flags
+//
+#undef FLAG
+#ifdef DEBUG
+#define FLAG FLAG_FULL
+#else
+#define FLAG FLAG_READONLY
+#endif
+
+// checks.cc
+DEFINE_bool(enable_slow_asserts, false,
+            "enable asserts that are slow to execute")
+
+// code-stubs.cc
+DEFINE_bool(print_code_stubs, false, "print code stubs")
+
+// codegen-ia32.cc / codegen-arm.cc
+DEFINE_bool(trace_codegen, false,
+            "print name of functions for which code is generated")
+DEFINE_bool(print_builtin_code, false, "print generated code for builtins")
+DEFINE_bool(print_source, false, "pretty print source code")
+DEFINE_bool(print_builtin_source, false,
+            "pretty print source code for builtins")
+DEFINE_bool(print_ast, false, "print source AST")
+DEFINE_bool(print_builtin_ast, false, "print source AST for builtins")
+DEFINE_bool(trace_calls, false, "trace calls")
+DEFINE_bool(trace_builtin_calls, false, "trace builtins calls")
+DEFINE_string(stop_at, "", "function name where to insert a breakpoint")
+
+// compiler.cc
+DEFINE_bool(print_builtin_scopes, false, "print scopes for builtins")
+DEFINE_bool(print_scopes, false, "print scopes")
+
+// contexts.cc
+DEFINE_bool(trace_contexts, false, "trace contexts operations")
+
+// heap.cc
+DEFINE_bool(gc_greedy, false, "perform GC prior to some allocations")
+DEFINE_bool(gc_verbose, false, "print stuff during garbage collection")
+DEFINE_bool(heap_stats, false, "report heap statistics before and after GC")
+DEFINE_bool(code_stats, false, "report code statistics after GC")
+DEFINE_bool(verify_heap, false, "verify heap pointers before and after GC")
+DEFINE_bool(print_handles, false, "report handles after GC")
+DEFINE_bool(print_global_handles, false, "report global handles after GC")
+DEFINE_bool(print_rset, false, "print remembered sets before GC")
+
+// ic.cc
+DEFINE_bool(trace_ic, false, "trace inline cache state transitions")
+
+// objects.cc
+DEFINE_bool(trace_normalization,
+            false,
+            "prints when objects are turned into dictionaries.")
+
+// runtime.cc
+DEFINE_bool(trace_lazy, false, "trace lazy compilation")
+
+// serialize.cc
+DEFINE_bool(debug_serialization, false,
+            "write debug information into the snapshot.")
+
+// spaces.cc
+DEFINE_bool(collect_heap_spill_statistics, false,
+            "report heap spill statistics along with heap_stats "
+            "(requires heap_stats)")
+
+//
+// Logging and profiling only flags
+//
+#undef FLAG
+#ifdef ENABLE_LOGGING_AND_PROFILING
+#define FLAG FLAG_FULL
+#else
+#define FLAG FLAG_READONLY
+#endif
+
+// log.cc
+DEFINE_bool(log, false,
+            "Minimal logging (no API, code, GC, suspect, or handles samples).")
+DEFINE_bool(log_all, false, "Log all events to the log file.")
+DEFINE_bool(log_api, false, "Log API events to the log file.")
+DEFINE_bool(log_code, false,
+            "Log code events to the log file without profiling.")
+DEFINE_bool(log_gc, false,
+            "Log heap samples on garbage collection for the hp2ps tool.")
+DEFINE_bool(log_handles, false, "Log global handle events.")
+DEFINE_bool(log_state_changes, false, "Log state changes.")
+DEFINE_bool(log_suspect, false, "Log suspect operations.")
+DEFINE_bool(prof, false,
+            "Log statistical profiling information (implies --log-code).")
+DEFINE_bool(log_regexp, false, "Log regular expression execution.")
+DEFINE_bool(sliding_state_window, false,
+            "Update sliding state window counters.")
+DEFINE_string(logfile, "v8.log", "Specify the name of the log file.")
+
+//
+// Disassembler only flags
+//
+#undef FLAG
+#ifdef ENABLE_DISASSEMBLER
+#define FLAG FLAG_FULL
+#else
+#define FLAG FLAG_READONLY
+#endif
+
+// codegen-ia32.cc / codegen-arm.cc
+DEFINE_bool(print_code, false, "print generated code")
+
+
+// Cleanup...
+#undef FLAG_FULL
+#undef FLAG_READONLY
+#undef FLAG
+
+#undef DEFINE_bool
+#undef DEFINE_int
+#undef DEFINE_string
+
+#undef FLAG_MODE_DECLARE
+#undef FLAG_MODE_DEFINE
+#undef FLAG_MODE_DEFINE_DEFAULTS
+#undef FLAG_MODE_META
diff --git a/src/flags.cc b/src/flags.cc
index 1f8413c..73bb855 100644
--- a/src/flags.cc
+++ b/src/flags.cc
@@ -34,220 +34,204 @@
 
 namespace v8 { namespace internal {
 
-// -----------------------------------------------------------------------------
-// Helpers
+// Define all of our flags.
+#define FLAG_MODE_DEFINE
+#include "flag-definitions.h"
 
-static inline char NormalizeChar(char ch) {
-  return ch == '_' ? '-' : ch;
-}
+// Define all of our flags default values.
+#define FLAG_MODE_DEFINE_DEFAULTS
+#include "flag-definitions.h"
 
+namespace {
 
-static const char* NormalizeName(const char* name) {
-  int len = strlen(name);
-  char* result = NewArray<char>(len + 1);
-  for (int i = 0; i <= len; i++) {
-    result[i] = NormalizeChar(name[i]);
+// This structure represents a single entry in the flag system, with a pointer
+// to the actual flag, default value, comment, etc.  This is designed to be POD
+// initialized as to avoid requiring static constructors.
+struct Flag {
+  enum FlagType { TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING };
+
+  FlagType type_;           // What type of flag, bool, int, or string.
+  const char* name_;        // Name of the flag, ex "my_flag".
+  void* valptr_;            // Pointer to the global flag variable.
+  const void* defptr_;      // Pointer to the default value.
+  const char* cmt_;         // A comment about the flags purpose.
+
+  FlagType type() const { return type_; }
+
+  const char* name() const { return name_; }
+
+  const char* comment() const { return cmt_; }
+
+  bool* bool_variable() const {
+    ASSERT(type_ == TYPE_BOOL);
+    return reinterpret_cast<bool*>(valptr_);
   }
-  return const_cast<const char*>(result);
-}
 
+  int* int_variable() const {
+    ASSERT(type_ == TYPE_INT);
+    return reinterpret_cast<int*>(valptr_);
+  }
 
-static bool EqualNames(const char* a, const char* b) {
-  for (int i = 0; NormalizeChar(a[i]) == NormalizeChar(b[i]); i++) {
-    if (a[i] == '\0') {
-      return true;
+  double* float_variable() const {
+    ASSERT(type_ == TYPE_FLOAT);
+    return reinterpret_cast<double*>(valptr_);
+  }
+
+  const char** string_variable() const {
+    ASSERT(type_ == TYPE_STRING);
+    return reinterpret_cast<const char**>(valptr_);
+  }
+
+  bool bool_default() const {
+    ASSERT(type_ == TYPE_BOOL);
+    return *reinterpret_cast<const bool*>(defptr_);
+  }
+
+  int int_default() const {
+    ASSERT(type_ == TYPE_INT);
+    return *reinterpret_cast<const int*>(defptr_);
+  }
+
+  double float_default() const {
+    ASSERT(type_ == TYPE_FLOAT);
+    return *reinterpret_cast<const double*>(defptr_);
+  }
+
+  const char* string_default() const {
+    ASSERT(type_ == TYPE_STRING);
+    return *reinterpret_cast<const char* const *>(defptr_);
+  }
+
+  // Compare this flag's current value against the default.
+  bool IsDefault() const {
+    switch (type_) {
+      case TYPE_BOOL:
+        return *bool_variable() == bool_default();
+      case TYPE_INT:
+        return *int_variable() == int_default();
+      case TYPE_FLOAT:
+        return *float_variable() == float_default();
+      case TYPE_STRING:
+        const char* str1 = *string_variable();
+        const char* str2 = string_default();
+        if (str2 == NULL) return str1 == NULL;
+        if (str1 == NULL) return str2 == NULL;
+        return strcmp(str1, str2) == 0;
+    }
+    UNREACHABLE();
+    return true;
+  }
+
+  // Set a flag back to it's default value.
+  void Reset() {
+    switch (type_) {
+      case TYPE_BOOL:
+        *bool_variable() = bool_default();
+        break;
+      case TYPE_INT:
+        *int_variable() = int_default();
+        break;
+      case TYPE_FLOAT:
+        *float_variable() = float_default();
+        break;
+      case TYPE_STRING:
+        *string_variable() = string_default();
+        break;
     }
   }
-  return false;
-}
+};
+
+Flag flags[] = {
+#define FLAG_MODE_META
+#include "flag-definitions.h"
+};
+
+const size_t num_flags = sizeof(flags) / sizeof(*flags);
+
+}  // namespace
 
 
-// -----------------------------------------------------------------------------
-// Implementation of Flag
-
-Flag::Flag(const char* file, const char* name, const char* comment,
-           Type type, void* variable, FlagValue default_) {
-  file_ = file;
-  name_ = NormalizeName(name);
-  comment_ = comment;
-  type_ = type;
-  variable_ = reinterpret_cast<FlagValue*>(variable);
-  this->default_ = default_;
-  FlagList::Register(this);
-}
-
-
-void Flag::SetToDefault() {
-  // Note that we cannot simply do '*variable_ = default_;' since
-  // flag variables are not really of type FlagValue and thus may
-  // be smaller! The FlagValue union is simply 'overlayed' on top
-  // of a flag variable for convenient access. Since union members
-  // are guarantee to be aligned at the beginning, this works.
-  switch (type_) {
-    case Flag::BOOL:
-      variable_->b = default_.b;
-      return;
-    case Flag::INT:
-      variable_->i = default_.i;
-      return;
-    case Flag::FLOAT:
-      variable_->f = default_.f;
-      return;
-    case Flag::STRING:
-      variable_->s = default_.s;
-      return;
-  }
-  UNREACHABLE();
-}
-
-
-bool Flag::IsDefault() const {
-  switch (type_) {
-    case Flag::BOOL:
-      return variable_->b == default_.b;
-    case Flag::INT:
-      return variable_->i == default_.i;
-    case Flag::FLOAT:
-      return variable_->f == default_.f;
-    case Flag::STRING:
-      if (variable_->s && default_.s) {
-        return strcmp(variable_->s, default_.s) == 0;
-      } else {
-        return variable_->s == default_.s;
-      }
-  }
-  UNREACHABLE();
-  return false;
-}
-
-
-static const char* Type2String(Flag::Type type) {
+static const char* Type2String(Flag::FlagType type) {
   switch (type) {
-    case Flag::BOOL: return "bool";
-    case Flag::INT: return "int";
-    case Flag::FLOAT: return "float";
-    case Flag::STRING: return "string";
+    case Flag::TYPE_BOOL: return "bool";
+    case Flag::TYPE_INT: return "int";
+    case Flag::TYPE_FLOAT: return "float";
+    case Flag::TYPE_STRING: return "string";
   }
   UNREACHABLE();
   return NULL;
 }
 
 
-static char* ToString(Flag::Type type, FlagValue* variable) {
-  char* value = NULL;
-  switch (type) {
-    case Flag::BOOL:
-      value = NewArray<char>(6);
-      OS::SNPrintF(value, 6, "%s", (variable->b ? "true" : "false"));
+static char* ToString(Flag* flag) {
+  Vector<char> value;
+  switch (flag->type()) {
+    case Flag::TYPE_BOOL:
+      value = Vector<char>::New(6);
+      OS::SNPrintF(value, "%s", (*flag->bool_variable() ? "true" : "false"));
       break;
-    case Flag::INT:
-      value = NewArray<char>(12);
-      OS::SNPrintF(value, 12, "%d", variable->i);
+    case Flag::TYPE_INT:
+      value = Vector<char>::New(12);
+      OS::SNPrintF(value, "%d", *flag->int_variable());
       break;
-    case Flag::FLOAT:
-      value = NewArray<char>(20);
-      OS::SNPrintF(value, 20, "%f", variable->f);
+    case Flag::TYPE_FLOAT:
+      value = Vector<char>::New(20);
+      OS::SNPrintF(value, "%f", *flag->float_variable());
       break;
-    case Flag::STRING:
-      if (variable->s) {
-        int length = strlen(variable->s) + 1;
-        value = NewArray<char>(length);
-        OS::SNPrintF(value, length, "%s", variable->s);
+    case Flag::TYPE_STRING:
+      const char* str = *flag->string_variable();
+      if (str) {
+        int length = strlen(str) + 1;
+        value = Vector<char>::New(length);
+        OS::SNPrintF(value, "%s", str);
       } else {
-        value = NewArray<char>(5);
-        OS::SNPrintF(value, 5, "NULL");
+        value = Vector<char>::New(5);
+        OS::SNPrintF(value, "NULL");
       }
       break;
   }
-  ASSERT(value != NULL);
-  return value;
+  ASSERT(!value.is_empty());
+  return value.start();
 }
 
 
-static void PrintFlagValue(Flag::Type type, FlagValue* variable) {
-  char* value = ToString(type, variable);
-  printf("%s", value);
-  DeleteArray(value);
-}
-
-
-char* Flag::StringValue() const {
-  return ToString(type_, variable_);
-}
-
-
-void Flag::Print(bool print_current_value) {
-  printf("  --%s (%s)  type: %s  default: ", name_, comment_,
-         Type2String(type_));
-  PrintFlagValue(type_, &default_);
-  if (print_current_value) {
-    printf("  current value: ");
-    PrintFlagValue(type_, variable_);
-  }
-  printf("\n");
-}
-
-
-// -----------------------------------------------------------------------------
-// Implementation of FlagList
-
-Flag* FlagList::list_ = NULL;
-
-
+// static
 List<char *>* FlagList::argv() {
   List<char *>* args = new List<char*>(8);
-  for (Flag* f = list_; f != NULL; f = f->next()) {
+  for (size_t i = 0; i < num_flags; ++i) {
+    Flag* f = &flags[i];
     if (!f->IsDefault()) {
-      char* cmdline_flag;
-      if (f->type() != Flag::BOOL || *(f->bool_variable())) {
+      Vector<char> cmdline_flag;
+      if (f->type() != Flag::TYPE_BOOL || *(f->bool_variable())) {
         int length = strlen(f->name()) + 2 + 1;
-        cmdline_flag = NewArray<char>(length);
-        OS::SNPrintF(cmdline_flag, length, "--%s", f->name());
+        cmdline_flag = Vector<char>::New(length);
+        OS::SNPrintF(cmdline_flag, "--%s", f->name());
       } else {
         int length = strlen(f->name()) + 4 + 1;
-        cmdline_flag = NewArray<char>(length);
-        OS::SNPrintF(cmdline_flag, length, "--no%s", f->name());
+        cmdline_flag = Vector<char>::New(length);
+        OS::SNPrintF(cmdline_flag, "--no%s", f->name());
       }
-      args->Add(cmdline_flag);
-      if (f->type() != Flag::BOOL) {
-        args->Add(f->StringValue());
+      args->Add(cmdline_flag.start());
+      if (f->type() != Flag::TYPE_BOOL) {
+        args->Add(ToString(f));
       }
     }
   }
+
   return args;
 }
 
 
-void FlagList::Print(const char* file, bool print_current_value) {
-  // Since flag registration is likely by file (= C++ file),
-  // we don't need to sort by file and still get grouped output.
-  const char* current = NULL;
-  for (Flag* f = list_; f != NULL; f = f->next()) {
-    if (file == NULL || file == f->file()) {
-      if (current != f->file()) {
-        printf("Flags from %s:\n", f->file());
-        current = f->file();
-      }
-      f->Print(print_current_value);
-    }
-  }
-}
-
-
-Flag* FlagList::Lookup(const char* name) {
-  Flag* f = list_;
-  while (f != NULL && !EqualNames(name, f->name()))
-    f = f->next();
-  return f;
-}
-
-
-void FlagList::SplitArgument(const char* arg,
-                             char* buffer,
-                             int buffer_size,
-                             const char** name,
-                             const char** value,
-                             bool* is_bool) {
+// Helper function to parse flags: Takes an argument arg and splits it into
+// a flag name and flag value (or NULL if they are missing). is_bool is set
+// if the arg started with "-no" or "--no". The buffer may be used to NUL-
+// terminate the name, it must be large enough to hold any possible name.
+static void SplitArgument(const char* arg,
+                          char* buffer,
+                          int buffer_size,
+                          const char** name,
+                          const char** value,
+                          bool* is_bool) {
   *name = NULL;
   *value = NULL;
   *is_bool = false;
@@ -282,6 +266,31 @@
 }
 
 
+inline char NormalizeChar(char ch) {
+  return ch == '_' ? '-' : ch;
+}
+
+
+static bool EqualNames(const char* a, const char* b) {
+  for (int i = 0; NormalizeChar(a[i]) == NormalizeChar(b[i]); i++) {
+    if (a[i] == '\0') {
+      return true;
+    }
+  }
+  return false;
+}
+
+
+static Flag* FindFlag(const char* name) {
+  for (size_t i = 0; i < num_flags; ++i) {
+    if (EqualNames(name, flags[i].name()))
+      return &flags[i];
+  }
+  return NULL;
+}
+
+
+// static
 int FlagList::SetFlagsFromCommandLine(int* argc,
                                       char** argv,
                                       bool remove_flags) {
@@ -299,7 +308,7 @@
 
     if (name != NULL) {
       // lookup the flag
-      Flag* flag = Lookup(name);
+      Flag* flag = FindFlag(name);
       if (flag == NULL) {
         if (remove_flags) {
           // We don't recognize this flag but since we're removing
@@ -314,7 +323,7 @@
       }
 
       // if we still need a flag value, use the next argument if available
-      if (flag->type() != Flag::BOOL && value == NULL) {
+      if (flag->type() != Flag::TYPE_BOOL && value == NULL) {
         if (i < *argc) {
           value = argv[i++];
         } else {
@@ -327,23 +336,23 @@
       // set the flag
       char* endp = const_cast<char*>("");  // *endp is only read
       switch (flag->type()) {
-        case Flag::BOOL:
+        case Flag::TYPE_BOOL:
           *flag->bool_variable() = !is_bool;
           break;
-        case Flag::INT:
+        case Flag::TYPE_INT:
           *flag->int_variable() = strtol(value, &endp, 10);  // NOLINT
           break;
-        case Flag::FLOAT:
+        case Flag::TYPE_FLOAT:
           *flag->float_variable() = strtod(value, &endp);
           break;
-        case Flag::STRING:
+        case Flag::TYPE_STRING:
           *flag->string_variable() = value;
           break;
       }
 
       // handle errors
-      if ((flag->type() == Flag::BOOL && value != NULL) ||
-          (flag->type() != Flag::BOOL && is_bool) ||
+      if ((flag->type() == Flag::TYPE_BOOL && value != NULL) ||
+          (flag->type() != Flag::TYPE_BOOL && is_bool) ||
           *endp != '\0') {
         fprintf(stderr, "Error: illegal value for flag %s of type %s\n",
                 arg, Type2String(flag->type()));
@@ -384,6 +393,7 @@
 }
 
 
+// static
 int FlagList::SetFlagsFromString(const char* str, int len) {
   // make a 0-terminated copy of str
   char* copy0 = NewArray<char>(len + 1);
@@ -427,12 +437,23 @@
 }
 
 
-void FlagList::Register(Flag* flag) {
-  ASSERT(flag != NULL && strlen(flag->name()) > 0);
-  if (Lookup(flag->name()) != NULL)
-    V8_Fatal(flag->file(), 0, "flag %s declared twice", flag->name());
-  flag->next_ = list_;
-  list_ = flag;
+// static
+void FlagList::ResetAllFlags() {
+  for (size_t i = 0; i < num_flags; ++i) {
+    flags[i].Reset();
+  }
+}
+
+
+// static
+void FlagList::PrintHelp() {
+  for (size_t i = 0; i < num_flags; ++i) {
+    Flag* f = &flags[i];
+    char* value = ToString(f);
+    printf("  --%s (%s)  type: %s  default: %s\n",
+           f->name(), f->comment(), Type2String(f->type()), value);
+    DeleteArray(value);
+  }
 }
 
 } }  // namespace v8::internal
diff --git a/src/flags.h b/src/flags.h
index 07eb691..813ea95 100644
--- a/src/flags.h
+++ b/src/flags.h
@@ -27,143 +27,17 @@
 #ifndef V8_FLAGS_H_
 #define V8_FLAGS_H_
 
+#include "checks.h"
+
 namespace v8 { namespace internal {
 
-// Internal use only.
-union FlagValue {
-  static FlagValue New_BOOL(bool b)  {
-    FlagValue v;
-    v.b = b;
-    return v;
-  }
-  static FlagValue New_INT(int i)  {
-    FlagValue v;
-    v.i = i;
-    return v;
-  }
-  static FlagValue New_FLOAT(float f)  {
-    FlagValue v;
-    v.f = f;
-    return v;
-  }
-  static FlagValue New_STRING(const char* s)  {
-    FlagValue v;
-    v.s = s;
-    return v;
-  }
-
-  bool b;
-  int i;
-  double f;
-  const char* s;
-};
-
-
-// Each flag can be accessed programmatically via a Flag object.
-class Flag {
- public:
-  enum Type { BOOL, INT, FLOAT, STRING };
-
-  // Internal use only.
-  Flag(const char* file, const char* name, const char* comment,
-       Type type, void* variable, FlagValue default_);
-
-  // General flag information
-  const char* file() const  { return file_; }
-  const char* name() const  { return name_; }
-  const char* comment() const  { return comment_; }
-
-  // Flag type
-  Type type() const  { return type_; }
-
-  // Flag variables
-  inline bool* bool_variable() const;
-  inline int* int_variable() const;
-  inline double* float_variable() const;
-  inline const char** string_variable() const;
-
-  // Default values
-  inline bool bool_default() const;
-  inline int int_default() const;
-  inline double float_default() const;
-  inline const char* string_default() const;
-
-  // Resets a flag to its default value
-  void SetToDefault();
-
-  // True if a flag is set to its default value
-  bool IsDefault() const;
-
-  // Iteration support
-  Flag* next() const  { return next_; }
-
-  // Prints flag information. The current flag value is only printed
-  // if print_current_value is set.
-  void Print(bool print_current_value);
-
-
-  // Returns the string formatted value of the flag. The caller is responsible
-  // for disposing the string.
-  char* StringValue() const;
-
- private:
-  const char* file_;
-  const char* name_;
-  const char* comment_;
-
-  Type type_;
-  FlagValue* variable_;
-  FlagValue default_;
-
-  Flag* next_;
-
-  friend class FlagList;  // accesses next_
-};
-
-
-// Internal use only.
-#define DEFINE_FLAG(type, c_type, name, default, comment) \
-  /* define and initialize the flag */                    \
-  c_type FLAG_##name = (default);                         \
-  /* register the flag */                                 \
-  static v8::internal::Flag Flag_##name(__FILE__,         \
-      #name,                                              \
-      (comment),                                          \
-      v8::internal::Flag::type,                           \
-      &FLAG_##name,                                       \
-      v8::internal::FlagValue::New_##type(default))
-
-
-// Internal use only.
-#define DECLARE_FLAG(c_type, name)              \
-  /* declare the external flag */               \
-  extern c_type FLAG_##name
-
-
-// Use the following macros to define a new flag:
-#define DEFINE_bool(name, default, comment) \
-  DEFINE_FLAG(BOOL, bool, name, default, comment)
-#define DEFINE_int(name, default, comment) \
-  DEFINE_FLAG(INT, int, name, default, comment)
-#define DEFINE_float(name, default, comment) \
-  DEFINE_FLAG(FLOAT, double, name, default, comment)
-#define DEFINE_string(name, default, comment) \
-  DEFINE_FLAG(STRING, const char*, name, default, comment)
-
-
-// Use the following macros to declare a flag defined elsewhere:
-#define DECLARE_bool(name)  DECLARE_FLAG(bool, name)
-#define DECLARE_int(name)  DECLARE_FLAG(int, name)
-#define DECLARE_float(name)  DECLARE_FLAG(double, name)
-#define DECLARE_string(name)  DECLARE_FLAG(const char*, name)
-
+// Declare all of our flags.
+#define FLAG_MODE_DECLARE
+#include "flag-definitions.h"
 
 // The global list of all flags.
 class FlagList {
  public:
-  // The NULL-terminated list of all flags. Traverse with Flag::next().
-  static Flag* list()  { return list_; }
-
   // The list of all flags with a value different from the default
   // and their values. The format of the list is like the format of the
   // argv array passed to the main function, e.g.
@@ -172,25 +46,6 @@
   // The caller is responsible for disposing the list.
   static List<char *>* argv();
 
-  // If file != NULL, prints information for all flags defined in file;
-  // otherwise prints information for all flags in all files. The current
-  // flag value is only printed if print_current_value is set.
-  static void Print(const char* file, bool print_current_value);
-
-  // Lookup a flag by name. Returns the matching flag or NULL.
-  static Flag* Lookup(const char* name);
-
-  // Helper function to parse flags: Takes an argument arg and splits it into
-  // a flag name and flag value (or NULL if they are missing). is_bool is set
-  // if the arg started with "-no" or "--no". The buffer may be used to NUL-
-  // terminate the name, it must be large enough to hold any possible name.
-  static void SplitArgument(const char* arg,
-                            char* buffer,
-                            int buffer_size,
-                            const char** name,
-                            const char** value,
-                            bool* is_bool);
-
   // Set the flag values by parsing the command line. If remove_flags is
   // set, the flags and associated values are removed from (argc,
   // argv). Returns 0 if no error occurred. Otherwise, returns the argv
@@ -211,12 +66,11 @@
   // and then calls SetFlagsFromCommandLine() and returns its result.
   static int SetFlagsFromString(const char* str, int len);
 
-  // Registers a new flag. Called during program initialization. Not
-  // thread-safe.
-  static void Register(Flag* flag);
+  // Reset all flags to their default value.
+  static void ResetAllFlags();
 
- private:
-  static Flag* list_;
+  // Print help to stdout with flags, types, and default values.
+  static void PrintHelp();
 };
 
 } }  // namespace v8::internal
diff --git a/src/frames-arm.cc b/src/frames-arm.cc
index 238eded..f7e7452 100644
--- a/src/frames-arm.cc
+++ b/src/frames-arm.cc
@@ -36,22 +36,16 @@
 
 StackFrame::Type StackFrame::ComputeType(State* state) {
   ASSERT(state->fp != NULL);
-  if (state->pp == NULL) {
-    if (Memory::Address_at(state->fp +
-                           EntryFrameConstants::kConstructMarkOffset) != 0) {
-      return ENTRY_CONSTRUCT;
-    } else {
-      return ENTRY;
-    }
-  } else if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
+  if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
     return ARGUMENTS_ADAPTOR;
-  } else if (
-      Memory::Object_at(state->fp +
-                        StandardFrameConstants::kFunctionOffset)->IsSmi()) {
-    return INTERNAL;
-  } else {
-    return JAVA_SCRIPT;
   }
+  // The marker and function offsets overlap. If the marker isn't a
+  // smi then the frame is a JavaScript frame -- and the marker is
+  // really the function.
+  const int offset = StandardFrameConstants::kMarkerOffset;
+  Object* marker = Memory::Object_at(state->fp + offset);
+  if (!marker->IsSmi()) return JAVA_SCRIPT;
+  return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
 }
 
 
@@ -69,7 +63,6 @@
   // Fill in the state.
   state->sp = sp;
   state->fp = fp;
-  state->pp = fp + ExitFrameConstants::kPPDisplacement;
   state->pc_address = reinterpret_cast<Address*>(sp - 1 * kPointerSize);
   return type;
 }
@@ -81,43 +74,49 @@
 
 
 int JavaScriptFrame::GetProvidedParametersCount() const {
-  const int offset = JavaScriptFrameConstants::kArgsLengthOffset;
-  int result = Memory::int_at(fp() + offset);
-  // We never remove extra parameters provided on the stack; we only
-  // fill in undefined values for parameters not provided.
-  ASSERT(0 <= result && result <= ComputeParametersCount());
-  return result;
+  return ComputeParametersCount();
 }
 
 
 Address JavaScriptFrame::GetCallerStackPointer() const {
-  return state_.pp;
+  int arguments;
+  if (Heap::gc_state() != Heap::NOT_IN_GC) {
+    // The arguments for cooked frames are traversed as if they were
+    // expression stack elements of the calling frame. The reason for
+    // this rather strange decision is that we cannot access the
+    // function during mark-compact GCs when the stack is cooked.
+    // In fact accessing heap objects (like function->shared() below)
+    // at all during GC is problematic.
+    arguments = 0;
+  } else {
+    // Compute the number of arguments by getting the number of formal
+    // parameters of the function. We must remember to take the
+    // receiver into account (+1).
+    JSFunction* function = JSFunction::cast(this->function());
+    arguments = function->shared()->formal_parameter_count() + 1;
+  }
+  const int offset = StandardFrameConstants::kCallerSPOffset;
+  return fp() + offset + (arguments * kPointerSize);
 }
 
 
 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const {
-  // Argument adaptor frames aren't used on ARM (yet).
-  UNIMPLEMENTED();
-  return 0;
+  const int arguments = Smi::cast(GetExpression(0))->value();
+  const int offset = StandardFrameConstants::kCallerSPOffset;
+  return fp() + offset + (arguments + 1) * kPointerSize;
 }
 
 
 Address InternalFrame::GetCallerStackPointer() const {
-  return state_.pp;
+  // Internal frames have no arguments. The stack pointer of the
+  // caller is at a fixed offset from the frame pointer.
+  return fp() + StandardFrameConstants::kCallerSPOffset;
 }
 
 
 Code* JavaScriptFrame::FindCode() const {
-  const int offset = StandardFrameConstants::kCodeOffset;
-  Object* code = Memory::Object_at(fp() + offset);
-  if (code == NULL) {
-    // The code object isn't set; find it and set it.
-    code = Heap::FindCodeObject(pc());
-    ASSERT(!code->IsFailure());
-    Memory::Object_at(fp() + offset) = code;
-  }
-  ASSERT(code != NULL);
-  return Code::cast(code);
+  JSFunction* function = JSFunction::cast(this->function());
+  return function->shared()->code();
 }
 
 
diff --git a/src/frames-arm.h b/src/frames-arm.h
index 463ae60..0d1a27c 100644
--- a/src/frames-arm.h
+++ b/src/frames-arm.h
@@ -93,8 +93,7 @@
 
 class EntryFrameConstants : public AllStatic {
  public:
-  static const int kCallerFPOffset      = -2 * kPointerSize;
-  static const int kConstructMarkOffset = -1 * kPointerSize;
+  static const int kCallerFPOffset      = -3 * kPointerSize;
 };
 
 
@@ -110,29 +109,23 @@
 
   // Let the parameters pointer for exit frames point just below the
   // frame structure on the stack.
-  static const int kPPDisplacement = 4 * kPointerSize;
+  static const int kPPDisplacement = 3 * kPointerSize;
 
   // The caller fields are below the frame pointer on the stack.
-  static const int kCallerPPOffset = +0 * kPointerSize;
-  static const int kCallerFPOffset = +1 * kPointerSize;
-  static const int kCallerPCOffset = +3 * kPointerSize;
+  static const int kCallerFPOffset = +0 * kPointerSize;
+  static const int kCallerPPOffset = +1 * kPointerSize;
+  static const int kCallerPCOffset = +2 * kPointerSize;
 };
 
 
 class StandardFrameConstants : public AllStatic {
  public:
-  static const int kExpressionsOffset = -4 * kPointerSize;
-  static const int kCodeOffset        = -3 * kPointerSize;
-  static const int kContextOffset     = -2 * kPointerSize;
-  static const int kCallerPPOffset    =  0 * kPointerSize;
-  static const int kCallerFPOffset    = +1 * kPointerSize;
-  static const int kCallerPCOffset    = +3 * kPointerSize;
-
-  // TODO(1233523): This is - of course - faked. The ARM port does not
-  // yet pass the callee function in a register, but the
-  // StackFrame::ComputeType code uses the field to figure out if a
-  // frame is a real JavaScript frame or an internal frame.
-  static const int kFunctionOffset = kContextOffset;
+  static const int kExpressionsOffset = -3 * kPointerSize;
+  static const int kMarkerOffset      = -2 * kPointerSize;
+  static const int kContextOffset     = -1 * kPointerSize;
+  static const int kCallerFPOffset    =  0 * kPointerSize;
+  static const int kCallerPCOffset    = +1 * kPointerSize;
+  static const int kCallerSPOffset    = +2 * kPointerSize;
 };
 
 
@@ -140,34 +133,32 @@
  public:
   // FP-relative.
   static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset;
-  static const int kArgsLengthOffset     = -1 * kPointerSize;
-  // 0 * kPointerSize : StandardFrameConstants::kCallerPPOffset
-  // 1 * kPointersize : StandardFrameConstents::kCallerFPOffset
-  static const int kSPOnExitOffset       = +2 * kPointerSize;
-  // 3 * kPointerSize : StandardFrameConstants::kCallerPCOffset
-  static const int kSavedRegistersOffset = +4 * kPointerSize;
+  static const int kSavedRegistersOffset = +2 * kPointerSize;
+  static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset;
 
   // PP-relative.
   static const int kParam0Offset   = -2 * kPointerSize;
   static const int kReceiverOffset = -1 * kPointerSize;
-  static const int kFunctionOffset =  0 * kPointerSize;
+};
+
+
+class ArgumentsAdaptorFrameConstants : public AllStatic {
+ public:
+  static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
 };
 
 
 class InternalFrameConstants : public AllStatic {
  public:
-  static const int kCodeOffset = StandardFrameConstants::kCodeOffset;
+  static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
 };
 
 
-inline Address StandardFrame::caller_pp() const {
-  return Memory::Address_at(fp() + StandardFrameConstants::kCallerPPOffset);
-}
-
-
 inline Object* JavaScriptFrame::function() const {
   const int offset = JavaScriptFrameConstants::kFunctionOffset;
-  return Memory::Object_at(pp() + offset);
+  Object* result = Memory::Object_at(fp() + offset);
+  ASSERT(result->IsJSFunction());
+  return result;
 }
 
 
diff --git a/src/frames.cc b/src/frames.cc
index 3b1a921..f5a72ec 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -35,14 +35,6 @@
 
 namespace v8 { namespace internal {
 
-
-DEFINE_int(max_stack_trace_source_length, 300,
-           "maximum length of function source code printed in a stack trace.");
-
-
-// -------------------------------------------------------------------------
-
-
 // Iterator that supports traversing the stack handlers of a
 // particular frame. Needs to know the top of the handler chain.
 class StackHandlerIterator BASE_EMBEDDED {
@@ -254,9 +246,6 @@
   // Setup the caller state.
   state->sp = pp();
   state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
-#ifdef USE_OLD_CALLING_CONVENTIONS
-  state->pp = Memory::Address_at(fp() + ExitFrameConstants::kCallerPPOffset);
-#endif
   state->pc_address
       = reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset);
   return ComputeType(state);
@@ -293,9 +282,6 @@
 StackFrame::Type StandardFrame::GetCallerState(State* state) const {
   state->sp = caller_sp();
   state->fp = caller_fp();
-#ifdef USE_OLD_CALLING_CONVENTIONS
-  state->pp = caller_pp();
-#endif
   state->pc_address = reinterpret_cast<Address*>(ComputePCAddress(fp()));
   return ComputeType(state);
 }
diff --git a/src/frames.h b/src/frames.h
index 9dc9319..44e9a91 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -164,9 +164,6 @@
   struct State {
     Address sp;
     Address fp;
-#ifdef USE_OLD_CALLING_CONVENTIONS
-    Address pp;
-#endif
     Address* pc_address;
   };
 
@@ -187,13 +184,9 @@
   // Compute the stack frame type for the given state.
   static Type ComputeType(State* state);
 
- protected:
-  // TODO(1233523): Once the ARM code uses the new calling
-  // conventions, we should be able to make state_ private again.
-  State state_;
-
  private:
   const StackFrameIterator* iterator_;
+  State state_;
 
   // Get the type and the state of the calling frame.
   virtual Type GetCallerState(State* state) const = 0;
@@ -338,9 +331,6 @@
   // Accessors.
   inline Address caller_sp() const;
   inline Address caller_fp() const;
-#ifdef USE_OLD_CALLING_CONVENTIONS
-  inline Address caller_pp() const;
-#endif
   inline Address caller_pc() const;
 
   // Computes the address of the PC field in the standard frame given
diff --git a/src/globals.h b/src/globals.h
index fa7038b..f2c9ac4 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -44,13 +44,6 @@
 #endif
 
 
-// TODO(1233523): Get rid of this code that conditionally introduces a
-// macro to allow us to check for platforms that use the old
-// non-adapted arguments calling conventions.
-#if defined(ARM) || defined(__arm__) || defined(__thumb__)
-#define USE_OLD_CALLING_CONVENTIONS
-#endif
-
 namespace v8 { namespace internal {
 
 // Support for alternative bool type. This is only enabled if the code is
diff --git a/src/handles.cc b/src/handles.cc
index 6c41a57..1fbb8ae 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -39,12 +39,6 @@
 
 namespace v8 { namespace internal {
 
-DECLARE_bool(allow_natives_syntax);
-
-#ifdef DEBUG
-DECLARE_bool(gc_greedy);
-#endif
-
 #define CALL_GC(RESULT)                                             \
   {                                                                 \
     Failure* __failure__ = Failure::cast(RESULT);                   \
@@ -56,34 +50,6 @@
   }
 
 
-// Don't use the following names: __object__, __failure__.
-#define CALL_HEAP_FUNCTION_VOID(FUNCTION_CALL)                      \
-  GC_GREEDY_CHECK();                                                \
-  Object* __object__ = FUNCTION_CALL;                               \
-  if (__object__->IsFailure()) {                                    \
-    if (__object__->IsRetryAfterGC()) {                             \
-      Failure* __failure__ = Failure::cast(__object__);             \
-      if (!Heap::CollectGarbage(__failure__->requested(),           \
-                                __failure__->allocation_space())) { \
-         /* TODO(1181417): Fix this. */                             \
-         V8::FatalProcessOutOfMemory("Handles");                    \
-      }                                                             \
-      __object__ = FUNCTION_CALL;                                   \
-      if (__object__->IsFailure()) {                                \
-        if (__object__->IsRetryAfterGC()) {                         \
-           /* TODO(1181417): Fix this. */                           \
-           V8::FatalProcessOutOfMemory("Handles");                  \
-        }                                                           \
-        return;                                                     \
-      }                                                             \
-    } else {                                                        \
-      return;                                                       \
-    }                                                               \
-  }
-
-
-
-
 Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray> content,
                                       Handle<JSArray> array) {
   CALL_HEAP_FUNCTION(content->AddKeysFromJSArray(*array), FixedArray);
diff --git a/src/heap-inl.h b/src/heap-inl.h
index c03c22c..ea6c480 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -33,12 +33,6 @@
 
 namespace v8 { namespace internal {
 
-#ifdef DEBUG
-DECLARE_bool(gc_greedy);
-DECLARE_int(gc_interval);
-#endif
-
-
 int Heap::MaxHeapObjectSize() {
   return Page::kMaxHeapObjectSize;
 }
@@ -196,6 +190,32 @@
   } while (false)
 
 
+// Don't use the following names: __object__, __failure__.
+#define CALL_HEAP_FUNCTION_VOID(FUNCTION_CALL)                      \
+  GC_GREEDY_CHECK();                                                \
+  Object* __object__ = FUNCTION_CALL;                               \
+  if (__object__->IsFailure()) {                                    \
+    if (__object__->IsRetryAfterGC()) {                             \
+      Failure* __failure__ = Failure::cast(__object__);             \
+      if (!Heap::CollectGarbage(__failure__->requested(),           \
+                                __failure__->allocation_space())) { \
+         /* TODO(1181417): Fix this. */                             \
+         V8::FatalProcessOutOfMemory("Handles");                    \
+      }                                                             \
+      __object__ = FUNCTION_CALL;                                   \
+      if (__object__->IsFailure()) {                                \
+        if (__object__->IsRetryAfterGC()) {                         \
+           /* TODO(1181417): Fix this. */                           \
+           V8::FatalProcessOutOfMemory("Handles");                  \
+        }                                                           \
+        return;                                                     \
+      }                                                             \
+    } else {                                                        \
+      return;                                                       \
+    }                                                               \
+  }
+
+
 #ifdef DEBUG
 
 inline bool Heap::allow_allocation(bool new_state) {
diff --git a/src/heap.cc b/src/heap.cc
index 5548fe9..b2aaf32 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -31,6 +31,7 @@
 #include "api.h"
 #include "bootstrapper.h"
 #include "codegen-inl.h"
+#include "compilation-cache.h"
 #include "debug.h"
 #include "global-handles.h"
 #include "jsregexp.h"
@@ -42,31 +43,6 @@
 
 namespace v8 { namespace internal {
 
-#ifdef DEBUG
-DEFINE_bool(gc_greedy, false, "perform GC prior to some allocations");
-DEFINE_bool(gc_verbose, false, "print stuff during garbage collection");
-DEFINE_bool(heap_stats, false, "report heap statistics before and after GC");
-DEFINE_bool(code_stats, false, "report code statistics after GC");
-DEFINE_bool(verify_heap, false, "verify heap pointers before and after GC");
-DEFINE_bool(print_handles, false, "report handles after GC");
-DEFINE_bool(print_global_handles, false, "report global handles after GC");
-DEFINE_bool(print_rset, false, "print remembered sets before GC");
-#endif
-
-DEFINE_int(new_space_size, 0, "size of (each semispace in) the new generation");
-DEFINE_int(old_space_size, 0, "size of the old generation");
-
-DEFINE_bool(gc_global, false, "always perform global GCs");
-DEFINE_int(gc_interval, -1, "garbage collect after <n> allocations");
-DEFINE_bool(trace_gc, false,
-            "print one trace line following each garbage collection");
-
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
-DECLARE_bool(log_gc);
-#endif
-
-
 #define ROOT_ALLOCATION(type, name) type* Heap::name##_;
   ROOT_LIST(ROOT_ALLOCATION)
 #undef ROOT_ALLOCATION
@@ -447,10 +423,7 @@
 
 
 void Heap::MarkCompactPrologue() {
-  // Empty eval caches
-  Heap::eval_cache_global_ = Heap::null_value();
-  Heap::eval_cache_non_global_ = Heap::null_value();
-
+  CompilationCache::MarkCompactPrologue();
   RegExpImpl::OldSpaceCollectionPrologue();
   Top::MarkCompactPrologue();
   ThreadManager::MarkCompactPrologue();
@@ -1208,9 +1181,8 @@
   if (obj->IsFailure()) return false;
   natives_source_cache_ = FixedArray::cast(obj);
 
-  // Initialized eval cache to null value.
-  eval_cache_global_ = null_value();
-  eval_cache_non_global_ = null_value();
+  // Initialize compilation cache.
+  CompilationCache::Clear();
 
   return true;
 }
@@ -2279,34 +2251,6 @@
 }
 
 
-Object* Heap::LookupEvalCache(bool is_global_context, String* src) {
-  Object* cache = is_global_context ?
-      eval_cache_global_ : eval_cache_non_global_;
-  return cache == null_value() ?
-      null_value() : EvalCache::cast(cache)->Lookup(src);
-}
-
-
-Object* Heap::PutInEvalCache(bool is_global_context, String* src,
-                             JSFunction* value) {
-  Object** cache_ptr = is_global_context ?
-      &eval_cache_global_ : &eval_cache_non_global_;
-
-  if (*cache_ptr == null_value()) {
-    Object* obj = EvalCache::Allocate(kInitialEvalCacheSize);
-    if (obj->IsFailure()) return false;
-    *cache_ptr = obj;
-  }
-
-  Object* new_cache =
-      EvalCache::cast(*cache_ptr)->Put(src, value);
-  if (new_cache->IsFailure()) return new_cache;
-  *cache_ptr = new_cache;
-
-  return value;
-}
-
-
 #ifdef DEBUG
 void Heap::ZapFromSpace() {
   ASSERT(HAS_HEAP_OBJECT_TAG(kFromSpaceZapValue));
@@ -2417,6 +2361,8 @@
   SYNCHRONIZE_TAG("top");
   Debug::Iterate(v);
   SYNCHRONIZE_TAG("debug");
+  CompilationCache::Iterate(v);
+  SYNCHRONIZE_TAG("compilationcache");
 
   // Iterate over local handles in handle scopes.
   HandleScopeImplementer::Iterate(v);
@@ -2515,11 +2461,11 @@
   // code space.  Align the pair of semispaces to their size, which must be
   // a power of 2.
   ASSERT(IsPowerOf2(young_generation_size_));
-  Address old_space_start = reinterpret_cast<Address>(chunk);
-  Address new_space_start = RoundUp(old_space_start, young_generation_size_);
-  Address code_space_start = new_space_start + young_generation_size_;
-  int old_space_size = new_space_start - old_space_start;
-  int code_space_size = young_generation_size_ - old_space_size;
+  Address code_space_start = reinterpret_cast<Address>(chunk);
+  Address new_space_start = RoundUp(code_space_start, young_generation_size_);
+  Address old_space_start = new_space_start + young_generation_size_;
+  int code_space_size = new_space_start - code_space_start;
+  int old_space_size = young_generation_size_ - code_space_size;
 
   // Initialize new space.
   new_space_ = new NewSpace(initial_semispace_size_,
diff --git a/src/heap.h b/src/heap.h
index 2fdcea2..bd16c88 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -122,9 +122,8 @@
   V(Code, c_entry_debug_break_code)                     \
   V(FixedArray, number_string_cache)                    \
   V(FixedArray, single_character_string_cache)          \
-  V(FixedArray, natives_source_cache)                   \
-  V(Object, eval_cache_global)                          \
-  V(Object, eval_cache_non_global)
+  V(FixedArray, natives_source_cache)
+
 
 #define ROOT_LIST(V)                                  \
   STRONG_ROOT_LIST(V)                                 \
@@ -531,28 +530,6 @@
   }
   static Object* LookupSymbol(String* str);
 
-  // EvalCache caches function boilerplates for compiled scripts
-  // from 'eval' function.
-  // Source string is used as the key, and compiled function
-  // boilerplate as value. Because the same source has different
-  // compiled code in global or local context, we use separate
-  // caches for global and local contexts.
-  // Caches are cleared before mark-compact/mark-sweep GC's.
-
-  // Finds the function boilerplate of a source string.
-  // It returns a JSFunction object if found in the cache.
-  // The first parameter specifies whether the code is
-  // compiled in a global context.
-  static Object* LookupEvalCache(bool is_global_context, String* src);
-
-  // Put a source string and its compiled function boilerplate
-  // in the eval cache.  The cache may expand, and returns failure
-  // if it cannot expand the cache, otherwise the value is returned.
-  // The first parameter specifies whether the boilerplate is
-  // compiled in a global context.
-  static Object* PutInEvalCache(bool is_global_context,
-                                String* src, JSFunction* value);
-
   // Compute the matching symbol map for a string if possible.
   // NULL is returned if string is in new space or not flattened.
   static Map* SymbolMapForString(String* str);
diff --git a/src/ic-arm.cc b/src/ic-arm.cc
index 61b516e..6977e17 100644
--- a/src/ic-arm.cc
+++ b/src/ic-arm.cc
@@ -407,17 +407,15 @@
   //  -- lr: return address
   // -----------------------------------
 
-  // Setup number of arguments for EnterJSFrame.
-  __ mov(r0, Operand(argc));
-  // Get the receiver of the function from the stack into r1.
-  __ ldr(r1, MemOperand(sp, argc * kPointerSize));
-  __ EnterJSFrame(0);
-  __ pop();  // remove the code slot
+  // Get the receiver of the function from the stack.
+  __ ldr(r2, MemOperand(sp, argc * kPointerSize));
+  // Get the name of the function to call from the stack.
+  __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
+
+  __ EnterInternalFrame();
 
   // Push the receiver and the name of the function.
-  __ ldr(r0, MemOperand(pp, 0));
-  __ mov(r2, Operand(0));  // code slot == 0
-  __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit());
+  __ stm(db_w, sp, r1.bit() | r2.bit());
 
   // Call the entry.
   __ mov(r0, Operand(2));
@@ -429,7 +427,7 @@
   // Move result to r1.
   __ mov(r1, Operand(r0));
 
-  __ ExitJSFrame(DO_NOT_RETURN);
+  __ ExitInternalFrame();
 
   // Patch the function on the stack; 1 ~ receiver.
   __ str(r1, MemOperand(sp, (argc + 1) * kPointerSize));
diff --git a/src/ic-ia32.cc b/src/ic-ia32.cc
index 6b0f2c4..37c35ee 100644
--- a/src/ic-ia32.cc
+++ b/src/ic-ia32.cc
@@ -34,10 +34,6 @@
 
 namespace v8 { namespace internal {
 
-
-DECLARE_bool(debug_code);
-
-
 // ----------------------------------------------------------------------------
 // Static IC stub generators.
 //
@@ -518,7 +514,7 @@
   __ mov(ebx, Operand(esp, (argc + 2) * kPointerSize));
 
   // Enter an internal frame.
-  __ EnterFrame(StackFrame::INTERNAL);
+  __ EnterInternalFrame();
 
   // Push the receiver and the name of the function.
   __ push(Operand(edx));
@@ -532,7 +528,7 @@
 
   // Move result to edi and exit the internal frame.
   __ mov(Operand(edi), eax);
-  __ ExitFrame(StackFrame::INTERNAL);
+  __ ExitInternalFrame();
 
   // Invoke the function.
   ParameterCount actual(argc);
diff --git a/src/ic.cc b/src/ic.cc
index baac44b..59794ea 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -38,13 +38,6 @@
 namespace v8 { namespace internal {
 
 #ifdef DEBUG
-DEFINE_bool(trace_ic, false, "trace inline cache state transitions");
-#endif
-DEFINE_bool(use_ic, true, "use inline caching");
-DECLARE_bool(strict);
-
-
-#ifdef DEBUG
 static char TransitionMarkFromState(IC::State state) {
   switch (state) {
     case UNINITIALIZED: return '0';
@@ -150,7 +143,8 @@
   // the receiver map's code cache.  Therefore, if the current target
   // is in the receiver map's code cache, the inline cache failed due
   // to prototype check failure.
-  if (map->IncludedInCodeCache(target)) {
+  int index = map->IndexInCodeCache(target);
+  if (index >= 0) {
     // For keyed load/store, the most likely cause of cache failure is
     // that the key has changed.  We do not distinguish between
     // prototype and non-prototype failures for keyed access.
@@ -159,14 +153,25 @@
       return MONOMORPHIC;
     }
 
-    // Clear the code cache for this map to avoid hitting the same
-    // invalid stub again.  It seems likely that most of the code in
-    // the cache is invalid if one of the stubs is so we flush the
-    // entire code cache.
-    map->ClearCodeCache();
+    // Remove the target from the code cache to avoid hitting the same
+    // invalid stub again.
+    map->RemoveFromCodeCache(index);
 
     return MONOMORPHIC_PROTOTYPE_FAILURE;
   }
+
+  // The builtins object is special.  It only changes when JavaScript
+  // builtins are loaded lazily.  It is important to keep inline
+  // caches for the builtins object monomorphic.  Therefore, if we get
+  // an inline cache miss for the builtins object after lazily loading
+  // JavaScript builtins, we clear the code cache and return
+  // uninitialized as the state to force the inline cache back to
+  // monomorphic state.
+  if (receiver->IsJSBuiltinsObject()) {
+    map->ClearCodeCache();
+    return UNINITIALIZED;
+  }
+
   return MONOMORPHIC;
 }
 
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 51bfd37..b59a3af 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -205,6 +205,8 @@
   value->set(INTERNAL_INDEX, *internal);
   re->set_value(*value);
 
+  LOG(RegExpCompileEvent(re));
+
   return re;
 }
 
@@ -223,6 +225,8 @@
     const JSRegExp* js_regexp =
         reinterpret_cast<JSRegExp*>(internal->GetDataStartAddress());
 
+    LOG(RegExpExecEvent(regexp, previous_index, subject));
+
     rc = jsRegExpExecute(js_regexp, two_byte_subject,
                        subject->length(),
                        previous_index,
diff --git a/src/log.cc b/src/log.cc
index dbefc04..a8159a0 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -37,28 +37,6 @@
 #ifdef ENABLE_LOGGING_AND_PROFILING
 
 //
-// Command line flags used by Logger.
-//
-DEFINE_bool(log, false,
-            "Minimal logging (no API, code, GC, suspect, or handles samples).");
-DEFINE_bool(log_all, false, "Log all events to the log file.");
-DEFINE_bool(log_api, false, "Log API events to the log file.");
-DEFINE_bool(log_code, false,
-            "Log code events to the log file without profiling.");
-DEFINE_bool(log_gc, false,
-            "Log heap samples on garbage collection for the hp2ps tool.");
-DEFINE_bool(log_handles, false, "Log global handle events.");
-DEFINE_bool(log_state_changes, false, "Log state changes.");
-DEFINE_bool(log_suspect, false, "Log suspect operations.");
-DEFINE_bool(prof, false,
-            "Log statistical profiling information (implies --log-code).");
-DEFINE_bool(sliding_state_window, false,
-            "Update sliding state window counters.");
-
-DEFINE_string(logfile, "v8.log", "Specify the name of the log file.");
-
-
-//
 // Sliding state window.  Updates counters to keep track of the last
 // window of kBufferSize states.  This is useful to track where we
 // spent our time.
@@ -368,6 +346,79 @@
 #endif
 }
 
+
+#ifdef ENABLE_LOGGING_AND_PROFILING
+void Logger::LogRegExpSource(Handle<JSValue> regexp) {
+  // Prints "/" + re.source + "/" +
+  //      (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")
+
+  Handle<Object> source = GetProperty(regexp, "source");
+  if (!source->IsString()) {
+    fprintf(logfile_, "no source");
+    return;
+  }
+  Handle<String> source_string = Handle<String>::cast(source);
+
+  SmartPointer<uc16> cstring = source_string->ToWideCString();
+  fprintf(logfile_, "/");
+  for (int i = 0, n = source_string->length(); i < n; i++) {
+    uc16 c = cstring[i];
+    if (c < 32 || (c > 126 && c <= 255)) {
+      fprintf(logfile_, "\\x%02x", c);
+    } else if (c > 255) {
+      fprintf(logfile_, "\\u%04x", c);
+    } else {
+      fprintf(logfile_, "%lc", c);
+    }
+  }
+  fprintf(logfile_, "/");
+
+  // global flag
+  Handle<Object> global = GetProperty(regexp, "global");
+  if (global->IsTrue()) {
+    fprintf(logfile_, "g");
+  }
+  // ignorecase flag
+  Handle<Object> ignorecase = GetProperty(regexp, "ignoreCase");
+  if (ignorecase->IsTrue()) {
+    fprintf(logfile_, "i");
+  }
+  // multiline flag
+  Handle<Object> multiline = GetProperty(regexp, "multiline");
+  if (multiline->IsTrue()) {
+    fprintf(logfile_, "m");
+  }
+}
+#endif  // ENABLE_LOGGING_AND_PROFILING
+
+
+void Logger::RegExpCompileEvent(Handle<JSValue> regexp) {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+  if (logfile_ == NULL || !FLAG_log_regexp) return;
+  ScopedLock sl(mutex_);
+
+  fprintf(logfile_, "regexp-compile,");
+  LogRegExpSource(regexp);
+  fprintf(logfile_, "\n");
+#endif
+}
+
+
+void Logger::RegExpExecEvent(Handle<JSValue> regexp,
+                             int start_index,
+                             Handle<String> input_string) {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+  if (logfile_ == NULL || !FLAG_log_regexp) return;
+  ScopedLock sl(mutex_);
+
+  fprintf(logfile_, "regexp-run,");
+  LogRegExpSource(regexp);
+  fprintf(logfile_, ",0x%08x,%d..%d\n",
+      input_string->Hash(), start_index, input_string->length());
+#endif
+}
+
+
 void Logger::ApiIndexedSecurityCheck(uint32_t index) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (logfile_ == NULL || !FLAG_log_api) return;
@@ -612,6 +663,7 @@
     FLAG_log_gc = true;
     FLAG_log_suspect = true;
     FLAG_log_handles = true;
+    FLAG_log_regexp = true;
   }
 
   // --prof implies --log-code.
@@ -620,7 +672,7 @@
   // Each of the individual log flags implies --log.  Check after
   // checking --log-all and --prof in case they set --log-code.
   if (FLAG_log_api || FLAG_log_code || FLAG_log_gc ||
-      FLAG_log_handles || FLAG_log_suspect) {
+      FLAG_log_handles || FLAG_log_suspect || FLAG_log_regexp) {
     FLAG_log = true;
   }
 
@@ -629,7 +681,7 @@
     if (strcmp(FLAG_logfile, "-") == 0) {
       logfile_ = stdout;
     } else {
-      logfile_ = fopen(FLAG_logfile, "w");
+      logfile_ = OS::FOpen(FLAG_logfile, "w");
     }
     mutex_ = OS::CreateMutex();
   }
diff --git a/src/log.h b/src/log.h
index 1c9d0b6..1e67fe9 100644
--- a/src/log.h
+++ b/src/log.h
@@ -40,7 +40,7 @@
 //
 // --log-all
 // Log all events to the file, default is off.  This is the same as combining
-// --log-api, --log-code, and --log-gc.
+// --log-api, --log-code, --log-gc, and --log-regexp.
 //
 // --log-api
 // Log API events to the logfile, default is off.  --log-api implies --log.
@@ -53,6 +53,10 @@
 // Log GC heap samples after each GC that can be processed by hp2ps, default
 // is off.  --log-gc implies --log.
 //
+// --log-regexp
+// Log creation and use of regular expressions, Default is off.
+// --log-regexp implies --log.
+//
 // --logfile <filename>
 // Specify the name of the logfile, default is "v8.log".
 //
@@ -174,6 +178,15 @@
                                  unsigned start,
                                  unsigned end);
 
+  // ==== Events logged by --log-regexp ====
+  // Regexp compilation and execution events.
+
+  static void RegExpCompileEvent(Handle<JSValue> regexp);
+
+  static void RegExpExecEvent(Handle<JSValue> regexp,
+                              int start_index,
+                              Handle<String> input_string);
+
 #ifdef ENABLE_LOGGING_AND_PROFILING
   static StateTag state() {
     return current_state_ ? current_state_->state() : OTHER;
@@ -182,6 +195,10 @@
 
 #ifdef ENABLE_LOGGING_AND_PROFILING
  private:
+
+  // Emits the source code of a regexp. Used by regexp events.
+  static void LogRegExpSource(Handle<JSValue> regexp);
+
   // Emits a profiler tick event. Used by the profiler thread.
   static void TickEvent(TickSample* sample, bool overflow);
 
diff --git a/src/macro-assembler-arm.cc b/src/macro-assembler-arm.cc
index 9817e42..d85a1de 100644
--- a/src/macro-assembler-arm.cc
+++ b/src/macro-assembler-arm.cc
@@ -34,10 +34,6 @@
 
 namespace v8 { namespace internal {
 
-DECLARE_bool(debug_code);
-DECLARE_bool(optimize_locals);
-
-
 // Give alias names to registers
 Register cp = {  8 };  // JavaScript context pointer
 Register pp = { 10 };  // parameter pointer
@@ -249,94 +245,28 @@
 }
 
 
-void MacroAssembler::EnterJSFrame(int argc) {
-  // Generate code entering a JS function called from a JS function
-  // stack: receiver, arguments
-  // r0: number of arguments (not including function, nor receiver)
-  // r1: preserved
-  // sp: stack pointer
-  // fp: frame pointer
-  // cp: callee's context
-  // pp: caller's parameter pointer
-  // lr: return address
+void MacroAssembler::EnterInternalFrame() {
+  // r0-r3: preserved
+  int type = StackFrame::INTERNAL;
 
-  // compute parameter pointer before making changes
-  // ip = sp + kPointerSize*(args_len+1);  // +1 for receiver
-  add(ip, sp, Operand(r0, LSL, kPointerSizeLog2));
-  add(ip, ip, Operand(kPointerSize));
-
-  // push extra parameters if we don't have enough
-  // (this can only happen if argc > 0 to begin with)
-  if (argc > 0) {
-    Label loop, done;
-
-    // assume enough arguments to be the most common case
-    sub(r2, r0, Operand(argc), SetCC);  // number of missing arguments
-    b(ge, &done);  // enough arguments
-
-    // not enough arguments
-    mov(r3, Operand(Factory::undefined_value()));
-    bind(&loop);
-    push(r3);
-    add(r2, r2, Operand(1), SetCC);
-    b(lt, &loop);
-
-    bind(&done);
-  }
-
-  mov(r3, Operand(r0));  // args_len to be saved
-  mov(r2, Operand(cp));  // context to be saved
-
-  // push in reverse order: context (r2), args_len (r3), caller_pp, caller_fp,
-  // sp_on_exit (ip == pp, may be patched on exit), return address
-  stm(db_w, sp, r2.bit() | r3.bit() | pp.bit() | fp.bit() |
-      ip.bit() | lr.bit());
-
-  // Setup new frame pointer.
-  add(fp, sp, Operand(-StandardFrameConstants::kContextOffset));
-  mov(pp, Operand(ip));  // setup new parameter pointer
-  mov(r0, Operand(0));  // spare slot to store caller code object during GC
-  push(r0);
-  // r1: preserved
+  stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
+  mov(ip, Operand(Smi::FromInt(type)));
+  push(ip);
+  mov(ip, Operand(0));
+  push(ip);  // Push an empty code cache slot.
+  add(fp, sp, Operand(3 * kPointerSize));  // Adjust FP to point to saved FP.
 }
 
 
-void MacroAssembler::ExitJSFrame(ExitJSFlag flag) {
-  // r0: result
-  // sp: stack pointer
-  // fp: frame pointer
-  // pp: parameter pointer
+void MacroAssembler::ExitInternalFrame() {
+  // r0: preserved
+  // r1: preserved
+  // r2: preserved
 
-  if (flag == DO_NOT_RETURN) {
-    add(r3, fp, Operand(JavaScriptFrameConstants::kSavedRegistersOffset));
-  }
-
-  if (flag == DO_NOT_RETURN) {
-    // restore sp as caller_sp (not as pp)
-    str(r3, MemOperand(fp, JavaScriptFrameConstants::kSPOnExitOffset));
-  }
-
-  if (flag == DO_NOT_RETURN && generating_stub()) {
-    // If we're generating a stub, we need to preserve the link
-    // register to be able to return to the place the stub was called
-    // from.
-    mov(ip, Operand(lr));
-  }
-
-  mov(sp, Operand(fp));  // respect ABI stack constraint
-  ldm(ia, sp, pp.bit() | fp.bit() | sp.bit() |
-      ((flag == RETURN) ? pc.bit() : lr.bit()));
-
-  if (flag == DO_NOT_RETURN && generating_stub()) {
-    // Return to the place where the stub was called without
-    // clobbering the value of the link register.
-    mov(pc, Operand(ip));
-  }
-
-  // r0: result
-  // sp: points to function arg (if return) or to last arg (if no return)
-  // fp: restored frame pointer
-  // pp: restored parameter pointer
+  // Drop the execution stack down to the frame pointer and restore the caller
+  // frame pointer and return address.
+  mov(sp, fp);
+  ldm(ia_w, sp, fp.bit() | lr.bit());
 }
 
 
@@ -346,12 +276,66 @@
                                     Register code_reg,
                                     Label* done,
                                     InvokeFlag flag) {
-  if (actual.is_immediate()) {
-    mov(r0, Operand(actual.immediate()));  // Push the number of arguments.
-  } else {
-    if (!actual.reg().is(r0)) {
-      mov(r0, Operand(actual.reg()));
+  bool definitely_matches = false;
+  Label regular_invoke;
+
+  // Check whether the expected and actual arguments count match. If not,
+  // setup registers according to contract with ArgumentsAdaptorTrampoline:
+  //  r0: actual arguments count
+  //  r1: function (passed through to callee)
+  //  r2: expected arguments count
+  //  r3: callee code entry
+
+  // The code below is made a lot easier because the calling code already sets
+  // up actual and expected registers according to the contract if values are
+  // passed in registers.
+  ASSERT(actual.is_immediate() || actual.reg().is(r0));
+  ASSERT(expected.is_immediate() || expected.reg().is(r2));
+  ASSERT((!code_constant.is_null() && code_reg.is(no_reg)) || code_reg.is(r3));
+
+  if (expected.is_immediate()) {
+    ASSERT(actual.is_immediate());
+    if (expected.immediate() == actual.immediate()) {
+      definitely_matches = true;
+    } else {
+      mov(r0, Operand(actual.immediate()));
+      const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
+      if (expected.immediate() == sentinel) {
+        // Don't worry about adapting arguments for builtins that
+        // don't want that done. Skip adaption code by making it look
+        // like we have a match between expected and actual number of
+        // arguments.
+        definitely_matches = true;
+      } else {
+        mov(r2, Operand(expected.immediate()));
+      }
     }
+  } else {
+    if (actual.is_immediate()) {
+      cmp(expected.reg(), Operand(actual.immediate()));
+      b(eq, &regular_invoke);
+      mov(r0, Operand(actual.immediate()));
+    } else {
+      cmp(expected.reg(), Operand(actual.reg()));
+      b(eq, &regular_invoke);
+    }
+  }
+
+  if (!definitely_matches) {
+    if (!code_constant.is_null()) {
+      mov(r3, Operand(code_constant));
+      add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
+    }
+
+    Handle<Code> adaptor =
+        Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
+    if (flag == CALL_FUNCTION) {
+      Call(adaptor, code_target);
+      b(done);
+    } else {
+      Jump(adaptor, code_target);
+    }
+    bind(&regular_invoke);
   }
 }
 
@@ -402,18 +386,8 @@
   // Contract with called JS functions requires that function is passed in r1.
   ASSERT(fun.is(r1));
 
-  Register code_reg = r3;
   Register expected_reg = r2;
-
-  // Make sure that the code and expected registers do not collide with the
-  // actual register being passed in.
-  if (actual.is_reg()) {
-    if (actual.reg().is(code_reg)) {
-      code_reg = r4;
-    } else if (actual.reg().is(expected_reg)) {
-      expected_reg = r4;
-    }
-  }
+  Register code_reg = r3;
 
   ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
   ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
@@ -507,7 +481,7 @@
     mov(r0, Operand(Smi::FromInt(StackHandler::kCodeNotPresent)));  // new TOS
     push(r0);
   } else {
-    // Must preserve r0-r3, r5-r7 are available.
+    // Must preserve r0-r4, r5-r7 are available.
     ASSERT(try_location == IN_JS_ENTRY);
     // The parameter pointer is meaningless here and fp does not point to a JS
     // frame. So we save NULL for both pp and fp. We expect the code throwing an
@@ -688,33 +662,54 @@
 }
 
 
-void MacroAssembler::InvokeBuiltin(const char* name,
-                                   int argc,
-                                   InvokeJSFlags flags) {
-  Handle<String> symbol = Factory::LookupAsciiSymbol(name);
-  Object* object = Top::security_context_builtins()->GetProperty(*symbol);
-  bool unresolved = true;
-  Code* code = Builtins::builtin(Builtins::Illegal);
+Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
+                                            bool* resolved) {
+  // Contract with compiled functions is that the function is passed in r1.
+  int builtins_offset =
+      JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
+  ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
+  ldr(r1, FieldMemOperand(r1, builtins_offset));
 
-  if (object->IsJSFunction()) {
-    Handle<JSFunction> function(JSFunction::cast(object));
-    if (function->is_compiled() || CompileLazy(function, CLEAR_EXCEPTION)) {
-      code = function->code();
-      unresolved = false;
-    }
-  }
+  return Builtins::GetCode(id, resolved);
+}
+
+
+void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
+                                   InvokeJSFlags flags) {
+  bool resolved;
+  Handle<Code> code = ResolveBuiltin(id, &resolved);
 
   if (flags == CALL_JS) {
-    Call(Handle<Code>(code), code_target);
+    Call(code, code_target);
   } else {
     ASSERT(flags == JUMP_JS);
-    Jump(Handle<Code>(code), code_target);
+    Jump(code, code_target);
   }
 
-  if (unresolved) {
+  if (!resolved) {
+    const char* name = Builtins::GetName(id);
+    int argc = Builtins::GetArgumentsCount(id);
     uint32_t flags =
         Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsIsPCRelative::encode(false);
+        Bootstrapper::FixupFlagsIsPCRelative::encode(true);
+    Unresolved entry = { pc_offset() - sizeof(Instr), flags, name };
+    unresolved_.Add(entry);
+  }
+}
+
+
+void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
+  bool resolved;
+  Handle<Code> code = ResolveBuiltin(id, &resolved);
+
+  mov(target, Operand(code));
+  if (!resolved) {
+    const char* name = Builtins::GetName(id);
+    int argc = Builtins::GetArgumentsCount(id);
+    uint32_t flags =
+        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
+        Bootstrapper::FixupFlagsIsPCRelative::encode(true);
     Unresolved entry = { pc_offset() - sizeof(Instr), flags, name };
     unresolved_.Add(entry);
   }
diff --git a/src/macro-assembler-arm.h b/src/macro-assembler-arm.h
index 4837f00..0af585d 100644
--- a/src/macro-assembler-arm.h
+++ b/src/macro-assembler-arm.h
@@ -98,21 +98,13 @@
   // ---------------------------------------------------------------------------
   // Activation frames
 
-  void EnterJSFrame(int argc);
-  void ExitJSFrame(ExitJSFlag flag);
+  void EnterInternalFrame();
+  void ExitInternalFrame();
 
 
   // ---------------------------------------------------------------------------
   // JavaScript invokes
 
-  // Helper functions for generating invokes.
-  void InvokePrologue(const ParameterCount& expected,
-                      const ParameterCount& actual,
-                      Handle<Code> code_constant,
-                      Register code_reg,
-                      Label* done,
-                      InvokeFlag flag);
-
   // Invoke the JavaScript function code by either calling or jumping.
   void InvokeCode(Register code,
                   const ParameterCount& expected,
@@ -131,6 +123,7 @@
                       const ParameterCount& actual,
                       InvokeFlag flag);
 
+
   // ---------------------------------------------------------------------------
   // Debugger Support
 
@@ -200,7 +193,11 @@
 
   // Invoke specified builtin JavaScript function. Adds an entry to
   // the unresolved list if the name does not resolve.
-  void InvokeBuiltin(const char* name, int argc, InvokeJSFlags flags);
+  void InvokeBuiltin(Builtins::JavaScript id, InvokeJSFlags flags);
+
+  // Store the code object for the given builtin in the target register and
+  // setup the function in r1.
+  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
 
   struct Unresolved {
     int pc;
@@ -233,6 +230,18 @@
   List<Unresolved> unresolved_;
   bool generating_stub_;
   bool allow_stub_calls_;
+
+  // Helper functions for generating invokes.
+  void InvokePrologue(const ParameterCount& expected,
+                      const ParameterCount& actual,
+                      Handle<Code> code_constant,
+                      Register code_reg,
+                      Label* done,
+                      InvokeFlag flag);
+
+  // Get the code for the given builtin. Returns if able to resolve
+  // the function in the 'resolved' flag.
+  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
 };
 
 
diff --git a/src/macro-assembler-ia32.cc b/src/macro-assembler-ia32.cc
index 50b43c9..b59735a 100644
--- a/src/macro-assembler-ia32.cc
+++ b/src/macro-assembler-ia32.cc
@@ -35,11 +35,6 @@
 
 namespace v8 { namespace internal {
 
-DECLARE_bool(debug_code);
-DEFINE_bool(native_code_counters, false,
-            "generate extra code for manipulating stats counters");
-
-
 MacroAssembler::MacroAssembler(void* buffer, int size)
     : Assembler(buffer, size),
       unresolved_(0),
@@ -319,21 +314,20 @@
 }
 
 
-void MacroAssembler::EnterFrame(StackFrame::Type type) {
-  ASSERT(type != StackFrame::JAVA_SCRIPT);
+void MacroAssembler::EnterInternalFrame() {
+  int type = StackFrame::INTERNAL;
+
   push(ebp);
   mov(ebp, Operand(esp));
   push(esi);
   push(Immediate(Smi::FromInt(type)));
-  if (type == StackFrame::INTERNAL) {
-    push(Immediate(0));
-  }
+  push(Immediate(0));  // Push an empty code cache slot.
 }
 
 
-void MacroAssembler::ExitFrame(StackFrame::Type type) {
-  ASSERT(type != StackFrame::JAVA_SCRIPT);
+void MacroAssembler::ExitInternalFrame() {
   if (FLAG_debug_code) {
+    StackFrame::Type type = StackFrame::INTERNAL;
     cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset),
         Immediate(Smi::FromInt(type)));
     Check(equal, "stack frame types must match");
@@ -578,7 +572,16 @@
       definitely_matches = true;
     } else {
       mov(eax, actual.immediate());
-      mov(ebx, expected.immediate());
+      const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
+      if (expected.immediate() == sentinel) {
+        // Don't worry about adapting arguments for builtins that
+        // don't want that done. Skip adaption code by making it look
+        // like we have a match between expected and actual number of
+        // arguments.
+        definitely_matches = true;
+      } else {
+        mov(ebx, expected.immediate());
+      }
     }
   } else {
     if (actual.is_immediate()) {
@@ -727,24 +730,8 @@
       JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
   mov(edi, FieldOperand(edx, builtins_offset));
 
-  Code* code = Builtins::builtin(Builtins::Illegal);
-  *resolved = false;
 
-  if (Top::security_context() != NULL) {
-    Object* object = Top::security_context_builtins()->javascript_builtin(id);
-    if (object->IsJSFunction()) {
-      Handle<JSFunction> function(JSFunction::cast(object));
-      // Make sure the number of parameters match the formal parameter count.
-      ASSERT(function->shared()->formal_parameter_count() ==
-             Builtins::GetArgumentsCount(id));
-      if (function->is_compiled() || CompileLazy(function, CLEAR_EXCEPTION)) {
-        code = function->code();
-        *resolved = true;
-      }
-    }
-  }
-
-  return Handle<Code>(code);
+  return Builtins::GetCode(id, resolved);
 }
 
 
diff --git a/src/macro-assembler-ia32.h b/src/macro-assembler-ia32.h
index 35fe73f..b3189c0 100644
--- a/src/macro-assembler-ia32.h
+++ b/src/macro-assembler-ia32.h
@@ -88,8 +88,8 @@
 
   // Enter or exit a stack frame of the given type. Cannot be used to
   // construct or leave JavaScript frames.
-  void EnterFrame(StackFrame::Type type);
-  void ExitFrame(StackFrame::Type type);
+  void EnterInternalFrame();
+  void ExitInternalFrame();
 
 
   // ---------------------------------------------------------------------------
@@ -120,10 +120,6 @@
   // Store the code object for the given builtin in the target register.
   void GetBuiltinEntry(Register target, Builtins::JavaScript id);
 
-  // Get the code for the given builtin. Returns if able to resolve
-  // the function in the 'resolved' flag.
-  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
-
   // Expression support
   void Set(Register dst, const Immediate& x);
   void Set(const Operand& dst, const Immediate& x);
@@ -251,6 +247,10 @@
                       const Operand& code_operand,
                       Label* done,
                       InvokeFlag flag);
+
+  // Get the code for the given builtin. Returns if able to resolve
+  // the function in the 'resolved' flag.
+  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
 };
 
 
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index e155e77..9ab6ae6 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -42,21 +42,8 @@
 // TODO(1240833): Fix the heap verification code and turn this into a real
 // flag.
 static const bool FLAG_verify_global_gc = false;
-
-DECLARE_bool(gc_verbose);
 #endif  // DEBUG
 
-DEFINE_bool(always_compact, false, "Perform compaction on every full GC");
-DEFINE_bool(never_compact, false,
-            "Never perform compaction on full GC - testing only");
-
-DEFINE_bool(cleanup_ics_at_gc, true,
-            "Flush inline caches prior to mark compact collection.");
-DEFINE_bool(cleanup_caches_in_maps_at_gc, true,
-            "Flush code caches in maps during mark compact cycle.");
-
-DECLARE_bool(gc_global);
-
 // ----------------------------------------------------------------------------
 // MarkCompactCollector
 
diff --git a/src/messages.cc b/src/messages.cc
index 6e8a371..7e3c0d6 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -46,7 +46,7 @@
   } else {
     HandleScope scope;
     Handle<Object> data(loc->script()->name());
-    SmartPointer<char> data_str = NULL;
+    SmartPointer<char> data_str;
     if (data->IsString())
       data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS);
     PrintF("%s:%i: %s\n", *data_str ? *data_str : "<unknown>",
diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index 5ee9511..d3de815 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -38,14 +38,6 @@
 #include "platform.h"
 #include "serialize.h"
 
-DEFINE_bool(h, false, "print this message");
-
-namespace v8 { namespace internal {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  DECLARE_bool(log_code);
-#endif
-} }
-
 // use explicit namespace to avoid clashing with types in namespace v8
 namespace i = v8::internal;
 using namespace v8;
@@ -124,7 +116,7 @@
 static int WriteInternalSnapshotToFile(const char* filename,
                                        const char* str,
                                        int size) {
-  FILE* f = fopen(filename, "wb");
+  FILE* f = i::OS::FOpen(filename, "wb");
   if (f == NULL) {
     i::OS::PrintError("Cannot open file %s for reading.\n", filename);
     return 0;
@@ -158,10 +150,10 @@
   // Print the usage if an error occurs when parsing the command line
   // flags or if the help flag is set.
   int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
-  if (result > 0 || argc != 2 || FLAG_h) {
+  if (result > 0 || argc != 2 || i::FLAG_h) {
     ::printf("Usage: %s [flag] ... outfile\n", argv[0]);
-    i::FlagList::Print(NULL, false);
-    return !FLAG_h;
+    i::FlagList::PrintHelp();
+    return !i::FLAG_h;
   }
 
   v8::V8::SetCounterFunction(counter_callback);
diff --git a/src/objects-inl.h b/src/objects-inl.h
index e690327..5bcf0a7 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -314,10 +314,8 @@
 }
 
 
-bool Object::IsEvalCache() {
-  return IsHashTable() &&
-      (this == Heap::eval_cache_global() ||
-       this == Heap::eval_cache_non_global());
+bool Object::IsCompilationCacheTable() {
+  return IsHashTable();
 }
 
 
@@ -1096,7 +1094,7 @@
 CAST_ACCESSOR(DescriptorArray)
 CAST_ACCESSOR(Dictionary)
 CAST_ACCESSOR(SymbolTable)
-CAST_ACCESSOR(EvalCache)
+CAST_ACCESSOR(CompilationCacheTable)
 CAST_ACCESSOR(String)
 CAST_ACCESSOR(SeqString)
 CAST_ACCESSOR(AsciiString)
@@ -1784,6 +1782,12 @@
               kFunctionTokenPositionOffset)
 
 
+void SharedFunctionInfo::DontAdaptArguments() {
+  ASSERT(code()->kind() == Code::BUILTIN);
+  set_formal_parameter_count(kDontAdaptArgumentsSentinel);
+}
+
+
 int SharedFunctionInfo::start_position() {
   return start_position_and_type() >> kStartPositionShift;
 }
diff --git a/src/objects.cc b/src/objects.cc
index 3f29c71..471864a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -43,12 +43,6 @@
 
 namespace v8 { namespace internal {
 
-#ifdef DEBUG
-DEFINE_bool(trace_normalization,
-            false,
-            "prints when objects are turned into dictionaries.");
-#endif
-
 // Getters and setters are stored in a fixed array property.  These are
 // constants for their indices.
 const int kGetterIndex = 0;
@@ -893,9 +887,9 @@
   // buffer that is plenty big enough for any floating point number, then
   // print that using vsnprintf (which may truncate but never allocate if
   // there is no more space in the buffer).
-  char buffer[100];
-  OS::SNPrintF(buffer, sizeof(buffer), "%.16g", Number());
-  accumulator->Add("%s", buffer);
+  EmbeddedVector<char, 100> buffer;
+  OS::SNPrintF(buffer, "%.16g", Number());
+  accumulator->Add("%s", buffer.start());
 }
 
 
@@ -2433,13 +2427,21 @@
 }
 
 
-bool Map::IncludedInCodeCache(Code* code) {
+int Map::IndexInCodeCache(Code* code) {
   FixedArray* array = code_cache();
   int len = array->length();
   for (int i = 0; i < len; i += 2) {
-    if (array->get(i+1) == code) return true;
+    if (array->get(i + 1) == code) return i + 1;
   }
-  return false;
+  return -1;
+}
+
+
+void Map::RemoveFromCodeCache(int index) {
+  FixedArray* array = code_cache();
+  ASSERT(array->length() >= index && array->get(index)->IsCode());
+  array->set_undefined(index - 1);  // key
+  array->set_undefined(index);  // code
 }
 
 
@@ -3023,11 +3025,11 @@
 }
 
 
-uc16* String::ToWideCString(RobustnessFlag robust_flag) {
+SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) {
   ASSERT(NativeAllocationChecker::allocation_allowed());
 
   if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
-    return NULL;
+    return SmartPointer<uc16>();
   }
 
   Access<StringInputBuffer> buffer(&string_input_buffer);
@@ -3041,7 +3043,7 @@
     result[i++] = character;
   }
   result[i] = 0;
-  return result;
+  return SmartPointer<uc16>(result);
 }
 
 
@@ -4195,6 +4197,21 @@
 }
 
 
+const char* Code::ICState2String(InlineCacheState state) {
+  switch (state) {
+    case UNINITIALIZED: return "UNINITIALIZED";
+    case PREMONOMORPHIC: return "PREMONOMORPHIC";
+    case MONOMORPHIC: return "MONOMORPHIC";
+    case MONOMORPHIC_PROTOTYPE_FAILURE: return "MONOMORPHIC_PROTOTYPE_FAILURE";
+    case MEGAMORPHIC: return "MEGAMORPHIC";
+    case DEBUG_BREAK: return "DEBUG_BREAK";
+    case DEBUG_PREPARE_STEP_IN: return "DEBUG_PREPARE_STEP_IN";
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
 void Code::Disassemble() {
   PrintF("kind = %s", Kind2String(kind()));
 
@@ -5576,7 +5593,7 @@
 }
 
 
-Object* EvalCache::Lookup(String* src) {
+Object* CompilationCacheTable::Lookup(String* src) {
   StringKey key(src);
   int entry = FindEntry(&key);
   if (entry != -1) {
@@ -5587,12 +5604,13 @@
 }
 
 
-Object* EvalCache::Put(String* src, Object* value) {
+Object* CompilationCacheTable::Put(String* src, Object* value) {
   StringKey key(src);
   Object* obj = EnsureCapacity(1, &key);
   if (obj->IsFailure()) return obj;
 
-  EvalCache* cache = reinterpret_cast<EvalCache*>(obj);
+  CompilationCacheTable* cache =
+      reinterpret_cast<CompilationCacheTable*>(obj);
   int entry = cache->FindInsertionEntry(src, key.Hash());
   cache->set(EntryToIndex(entry), src);
   cache->set(EntryToIndex(entry) + 1, value);
diff --git a/src/objects.h b/src/objects.h
index ba9de24..0957a9f 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -614,7 +614,7 @@
   inline bool IsHashTable();
   inline bool IsDictionary();
   inline bool IsSymbolTable();
-  inline bool IsEvalCache();
+  inline bool IsCompilationCacheTable();
   inline bool IsPrimitive();
   inline bool IsGlobalObject();
   inline bool IsJSGlobalObject();
@@ -1818,19 +1818,16 @@
 };
 
 
-// EvalCache for caching eval'ed string and function.
-//
-// The cache is cleaned up during a mark-compact GC.
-class EvalCache: public HashTable<0, 2> {
+class CompilationCacheTable: public HashTable<0, 2> {
  public:
   // Find cached value for a string key, otherwise return null.
   Object* Lookup(String* src);
   Object* Put(String* src, Object* value);
 
-  static inline EvalCache* cast(Object* obj);
+  static inline CompilationCacheTable* cast(Object* obj);
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(EvalCache);
+  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
 };
 
 
@@ -2066,6 +2063,7 @@
 #ifdef ENABLE_DISASSEMBLER
   // Printing
   static const char* Kind2String(Kind kind);
+  static const char* ICState2String(InlineCacheState state);
   void Disassemble();
 #endif  // ENABLE_DISASSEMBLER
 
@@ -2346,8 +2344,12 @@
   // Returns the found code or undefined if absent.
   Object* FindInCodeCache(String* name, Code::Flags flags);
 
-  // Tells whether code is in the code cache.
-  bool IncludedInCodeCache(Code* code);
+  // Returns the non-negative index of the code object if it is in the
+  // cache and -1 otherwise.
+  int IndexInCodeCache(Code* code);
+
+  // Removes a code object from the code cache at the given index.
+  void RemoveFromCodeCache(int index);
 
   // Dispatched behavior.
   void MapIterateBody(ObjectVisitor* v);
@@ -2467,6 +2469,10 @@
   inline int formal_parameter_count();
   inline void set_formal_parameter_count(int value);
 
+  // Set the formal parameter count so the function code will be
+  // called without using argument adaptor frames.
+  inline void DontAdaptArguments();
+
   // [expected_nof_properties]: Expected number of properties for the function.
   inline int expected_nof_properties();
   inline void set_expected_nof_properties(int value);
@@ -2536,6 +2542,9 @@
   // Casting.
   static inline SharedFunctionInfo* cast(Object* obj);
 
+  // Constants.
+  static const int kDontAdaptArgumentsSentinel = -1;
+
   // Layout description.
   static const int kNameOffset = HeapObject::kSize;
   static const int kCodeOffset = kNameOffset + kPointerSize;
@@ -2864,7 +2873,8 @@
   // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust  This means it
   // handles unexpected data without causing assert failures and it does not
   // do any heap allocations.  This is useful when printing stack traces.
-  uc16* ToWideCString(RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL);
+  SmartPointer<uc16> ToWideCString(
+      RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL);
 
   // Tells whether the hash code has been computed.
   inline bool HasHashCode();
diff --git a/src/parser.cc b/src/parser.cc
index 5d7ed0f..b385f16 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -37,10 +37,6 @@
 
 namespace v8 { namespace internal {
 
-DECLARE_bool(lazy);
-DEFINE_bool(allow_natives_syntax, false, "allow natives syntax");
-
-
 class ParserFactory;
 class ParserLog;
 class TemporaryScope;
@@ -1142,6 +1138,8 @@
   // builtins.cc:HandleApiCall to perform argument type checks and to
   // find the right native code to call.
   boilerplate->shared()->set_function_data(fun->shared()->function_data());
+  int parameters = fun->shared()->formal_parameter_count();
+  boilerplate->shared()->set_formal_parameter_count(parameters);
 
   // TODO(1240846): It's weird that native function declarations are
   // introduced dynamically when we meet their declarations, whereas
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index ba72768..9589bf9 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -126,6 +126,11 @@
 }
 
 
+FILE* OS::FOpen(const char* path, const char* mode) {
+  return fopen(path, mode);
+}
+
+
 void OS::Print(const char* format, ...) {
   va_list args;
   va_start(args, format);
@@ -152,19 +157,21 @@
 }
 
 
-int OS::SNPrintF(char* str, size_t size, const char* format, ...) {
+int OS::SNPrintF(Vector<char> str, const char* format, ...) {
   va_list args;
   va_start(args, format);
-  int result = VSNPrintF(str, size, format, args);
+  int result = VSNPrintF(str, format, args);
   va_end(args);
   return result;
 }
 
 
-int OS::VSNPrintF(char* str, size_t size, const char* format, va_list args) {
-  int n = vsnprintf(str, size, format, args);  // forward to linux.
-  if (n < 0 || static_cast<size_t>(n) >= size) {
-    str[size - 1] = '\0';
+int OS::VSNPrintF(Vector<char> str,
+                  const char* format,
+                  va_list args) {
+  int n = vsnprintf(str.start(), str.length(), format, args);
+  if (n < 0 || n >= str.length()) {
+    str[str.length() - 1] = '\0';
     return -1;
   } else {
     return n;
@@ -172,6 +179,21 @@
 }
 
 
+void OS::StrNCpy(Vector<char> dest, const char* src, size_t n) {
+  strncpy(dest.start(), src, n);
+}
+
+
+void OS::WcsCpy(Vector<wchar_t> dest, const wchar_t* src) {
+  wcscpy(dest.start(), src);
+}
+
+
+char *OS::StrDup(const char* str) {
+  return strdup(str);
+}
+
+
 double OS::nan_value() { return NAN; }
 
 // We keep the lowest and highest addresses mapped as a quick way of
@@ -341,7 +363,9 @@
     frames[i].address = addresses[i];
     // Format a text representation of the frame based on the information
     // available.
-    SNPrintF(frames[i].text, kStackWalkMaxTextLen, "%s", symbols[i]);
+    SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen),
+             "%s",
+             symbols[i]);
     // Make sure line termination is in place.
     frames[i].text[kStackWalkMaxTextLen - 1] = '\0';
   }
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index 7573125..54aad6a 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -132,6 +132,11 @@
 }
 
 
+FILE* OS::FOpen(const char* path, const char* mode) {
+  return fopen(path, mode);
+}
+
+
 void OS::Print(const char* format, ...) {
   va_list args;
   va_start(args, format);
@@ -158,19 +163,21 @@
 }
 
 
-int OS::SNPrintF(char* str, size_t size, const char* format, ...) {
+int OS::SNPrintF(Vector<char> str, const char* format, ...) {
   va_list args;
   va_start(args, format);
-  int result = VSNPrintF(str, size, format, args);
+  int result = VSNPrintF(str, format, args);
   va_end(args);
   return result;
 }
 
 
-int OS::VSNPrintF(char* str, size_t size, const char* format, va_list args) {
-  int n = vsnprintf(str, size, format, args);  // forward to Mac OS X.
-  if (n < 0 || static_cast<size_t>(n) >= size) {
-    str[size - 1] = '\0';
+int OS::VSNPrintF(Vector<char> str,
+                  const char* format,
+                  va_list args) {
+  int n = vsnprintf(str.start(), str.length(), format, args);
+  if (n < 0 || n >= str.length()) {
+    str[str.length() - 1] = '\0';
     return -1;
   } else {
     return n;
@@ -178,6 +185,21 @@
 }
 
 
+void OS::StrNCpy(Vector<char> dest, const char* src, size_t n) {
+  strncpy(dest.start(), src, n);
+}
+
+
+void OS::WcsCpy(Vector<wchar_t> dest, const wchar_t* src) {
+  wcscpy(dest.start(), src);
+}
+
+
+char *OS::StrDup(const char* str) {
+  return strdup(str);
+}
+
+
 // We keep the lowest and highest addresses mapped as a quick way of
 // determining that pointers are outside the heap (used mostly in assertions
 // and verification).  The estimate is conservative, ie, not all addresses in
@@ -299,7 +321,10 @@
     frames[i].address = addresses[i];
     // Format a text representation of the frame based on the information
     // available.
-    SNPrintF(frames[i].text, kStackWalkMaxTextLen, "%s", symbols[i]);
+    SNPrintF(MutableCStrVector(frames[i].text,
+                               kStackWalkMaxTextLen),
+             "%s",
+             symbols[i]);
     // Make sure line termination is in place.
     frames[i].text[kStackWalkMaxTextLen - 1] = '\0';
   }
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 6035465..747f0a4 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -156,14 +156,14 @@
 // Case-insensitive string comparisons. Use stricmp() on Win32. Usually defined
 // in strings.h.
 int strcasecmp(const char* s1, const char* s2) {
-  return stricmp(s1, s2);
+  return _stricmp(s1, s2);
 }
 
 
 // Case-insensitive bounded string comparisons. Use stricmp() on Win32. Usually
 // defined in strings.h.
 int strncasecmp(const char* s1, const char* s2, int n) {
-  return strnicmp(s1, s2, n);
+  return _strnicmp(s1, s2, n);
 }
 
 namespace v8 { namespace internal {
@@ -341,9 +341,13 @@
   }
 
   // Make standard and DST timezone names.
-  _snprintf(std_tz_name_, kTzNameSize, "%S", tzinfo_.StandardName);
+  OS::SNPrintF(Vector<char>(std_tz_name_, kTzNameSize),
+               "%S",
+               tzinfo_.StandardName);
   std_tz_name_[kTzNameSize - 1] = '\0';
-  _snprintf(dst_tz_name_, kTzNameSize, "%S", tzinfo_.DaylightName);
+  OS::SNPrintF(Vector<char>(dst_tz_name_, kTzNameSize),
+               "%S",
+               tzinfo_.DaylightName);
   dst_tz_name_[kTzNameSize - 1] = '\0';
 
   // If OS returned empty string or resource id (like "@tzres.dll,-211")
@@ -351,12 +355,14 @@
   // To properly resolve the resource identifier requires a library load,
   // which is not possible in a sandbox.
   if (std_tz_name_[0] == '\0' || std_tz_name_[0] == '@') {
-    _snprintf(std_tz_name_, kTzNameSize - 1, "%s Standard Time",
-              GuessTimezoneNameFromBias(tzinfo_.Bias));
+    OS::SNPrintF(Vector<char>(std_tz_name_, kTzNameSize - 1),
+                 "%s Standard Time",
+                 GuessTimezoneNameFromBias(tzinfo_.Bias));
   }
   if (dst_tz_name_[0] == '\0' || dst_tz_name_[0] == '@') {
-    _snprintf(dst_tz_name_, kTzNameSize - 1, "%s Daylight Time",
-              GuessTimezoneNameFromBias(tzinfo_.Bias));
+    OS::SNPrintF(Vector<char>(dst_tz_name_, kTzNameSize - 1),
+                 "%s Daylight Time",
+                 GuessTimezoneNameFromBias(tzinfo_.Bias));
   }
 
   // Timezone information initialized.
@@ -607,10 +613,19 @@
     // It is important to use safe print here in order to avoid
     // overflowing the buffer. We might truncate the output, but this
     // does not crash.
-    static const int kBufferSize = 4096;
-    char buffer[kBufferSize];
-    OS::VSNPrintF(buffer, kBufferSize, format, args);
-    OutputDebugStringA(buffer);
+    EmbeddedVector<char, 4096> buffer;
+    OS::VSNPrintF(buffer, format, args);
+    OutputDebugStringA(buffer.start());
+  }
+}
+
+
+FILE* OS::FOpen(const char* path, const char* mode) {
+  FILE* result;
+  if (fopen_s(&result, path, mode) == 0) {
+    return result;
+  } else {
+    return NULL;
   }
 }
 
@@ -643,24 +658,21 @@
 }
 
 
-int OS::SNPrintF(char* str, size_t size, const char* format, ...) {
+int OS::SNPrintF(Vector<char> str, const char* format, ...) {
   va_list args;
   va_start(args, format);
-  int result = VSNPrintF(str, size, format, args);
+  int result = VSNPrintF(str, format, args);
   va_end(args);
   return result;
 }
 
 
-int OS::VSNPrintF(char* str, size_t size, const char* format, va_list args) {
-  // Print formated output to string. The _vsnprintf function has been
-  // deprecated in MSVC. We need to define _CRT_NONSTDC_NO_DEPRECATE
-  // during compilation to use it anyway. Usually defined in stdio.h.
-  int n = _vsnprintf(str, size, format, args);
+int OS::VSNPrintF(Vector<char> str, const char* format, va_list args) {
+  int n = _vsnprintf_s(str.start(), str.length(), _TRUNCATE, format, args);
   // Make sure to zero-terminate the string if the output was
   // truncated or if there was an error.
-  if (n < 0 || static_cast<size_t>(n) >= size) {
-    str[size - 1] = '\0';
+  if (n < 0 || n >= str.length()) {
+    str[str.length() - 1] = '\0';
     return -1;
   } else {
     return n;
@@ -668,6 +680,25 @@
 }
 
 
+void OS::StrNCpy(Vector<char> dest, const char* src, size_t n) {
+  int result = strncpy_s(dest.start(), dest.length(), src, n);
+  USE(result);
+  ASSERT(result == 0);
+}
+
+
+void OS::WcsCpy(Vector<wchar_t> dest, const wchar_t* src) {
+  int result = wcscpy_s(dest.start(), dest.length(), src);
+  USE(result);
+  ASSERT(result == 0);
+}
+
+
+char *OS::StrDup(const char* str) {
+  return _strdup(str);
+}
+
+
 // We keep the lowest and highest addresses mapped as a quick way of
 // determining that pointers are outside the heap (used mostly in assertions
 // and verification).  The estimate is conservative, ie, not all addresses in
@@ -1132,11 +1163,15 @@
       // Format a text representation of the frame based on the information
       // available.
       if (ok) {
-        SNPrintF(frames[frames_count].text, kStackWalkMaxTextLen, "%s %s:%d:%d",
+        SNPrintF(MutableCStrVector(frames[frames_count].text,
+                                   kStackWalkMaxTextLen),
+                 "%s %s:%d:%d",
                  symbol->Name, Line.FileName, Line.LineNumber,
                  line_displacement);
       } else {
-        SNPrintF(frames[frames_count].text, kStackWalkMaxTextLen, "%s",
+        SNPrintF(MutableCStrVector(frames[frames_count].text,
+                                   kStackWalkMaxTextLen),
+                 "%s",
                  symbol->Name);
       }
       // Make sure line termination is in place.
diff --git a/src/platform.h b/src/platform.h
index 1cb42d2..5bb7f20 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -132,6 +132,8 @@
   // Returns the daylight savings offset for the given time.
   static double DaylightSavingsOffset(double time);
 
+  static FILE* FOpen(const char* path, const char* mode);
+
   // Print output to console. This is mostly used for debugging output.
   // On platforms that has standard terminal output, the output
   // should go to stdout.
@@ -198,12 +200,15 @@
 
   // Safe formatting print. Ensures that str is always null-terminated.
   // Returns the number of chars written, or -1 if output was truncated.
-  static int SNPrintF(char* str, size_t size, const char* format, ...);
-  static int VSNPrintF(char* str,
-                       size_t size,
+  static int SNPrintF(Vector<char> str, const char* format, ...);
+  static int VSNPrintF(Vector<char> str,
                        const char* format,
                        va_list args);
 
+  static void StrNCpy(Vector<char> dest, const char* src, size_t n);
+  static void WcsCpy(Vector<wchar_t> dest, const wchar_t* src);
+  static char* StrDup(const char* str);
+
   // Support for profiler.  Can do nothing, in which case ticks
   // occuring in shared libraries will not be properly accounted
   // for.
diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
index 2f377d8..fef270e 100644
--- a/src/prettyprinter.cc
+++ b/src/prettyprinter.cc
@@ -448,8 +448,9 @@
   for (;;) {
     va_list arguments;
     va_start(arguments, format);
-    int available = size_ - pos_;
-    int n = OS::VSNPrintF(output_ + pos_, available, format, arguments);
+    int n = OS::VSNPrintF(Vector<char>(output_, size_) + pos_,
+                          format,
+                          arguments);
     va_end(arguments);
 
     if (n >= 0) {
@@ -648,10 +649,10 @@
   if (var == NULL) {
     PrintLiteralIndented(info, value, true);
   } else {
-    char buf[256];
-    OS::SNPrintF(buf, sizeof(buf), "%s (mode = %s)", info,
+    EmbeddedVector<char, 256> buf;
+    OS::SNPrintF(buf, "%s (mode = %s)", info,
                  Variable::Mode2String(var->mode()));
-    PrintLiteralIndented(buf, value, true);
+    PrintLiteralIndented(buf.start(), value, true);
   }
 }
 
@@ -1019,10 +1020,10 @@
 
 
 void AstPrinter::VisitCountOperation(CountOperation* node) {
-  char buf[128];
-  OS::SNPrintF(buf, sizeof(buf), "%s %s", (node->is_prefix() ? "PRE" : "POST"),
+  EmbeddedVector<char, 128> buf;
+  OS::SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
                Token::Name(node->op()));
-  PrintIndentedVisit(buf, node->expression());
+  PrintIndentedVisit(buf.start(), node->expression());
 }
 
 
diff --git a/src/runtime.cc b/src/runtime.cc
index 5bab875..c579a20 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -159,22 +159,9 @@
   // literal.
   ASSERT(args.length() == 2);
   CONVERT_CHECKED(FixedArray, elements, args[0]);
-
-#ifdef USE_OLD_CALLING_CONVENTIONS
-  ASSERT(args[1]->IsTheHole());
-  // TODO(1332579): Pass in the literals array from the function once
-  // the new calling convention is in place on ARM.  Currently, we
-  // retrieve the array constructor from the global context.  This is
-  // a security problem since the global object might have been
-  // reinitialized and the array constructor from the global context
-  // might be from a context that we are not allowed to access.
-  JSFunction* constructor =
-      JSFunction::cast(Top::context()->global_context()->array_function());
-#else
   CONVERT_CHECKED(FixedArray, literals, args[1]);
   const int kArrayFunIndex = JSFunction::kLiteralArrayFunctionIndex;
   JSFunction* constructor = JSFunction::cast(literals->get(kArrayFunIndex));
-#endif
 
   // Create the JSArray.
   Object* object = Heap::AllocateJSObject(constructor);
@@ -2736,11 +2723,6 @@
 }
 
 
-#ifdef DEBUG
-DEFINE_bool(trace_lazy, false, "trace lazy compilation");
-#endif
-
-
 static Object* Runtime_LazyCompile(Arguments args) {
   HandleScope scope;
   ASSERT(args.length() == 1);
@@ -3364,6 +3346,7 @@
 static Object* Runtime_CompileString(Arguments args) {
   HandleScope scope;
   ASSERT(args.length() == 2);
+  CONVERT_ARG_CHECKED(String, source, 0);
   bool contextual = args[1]->IsTrue();
   RUNTIME_ASSERT(contextual || args[1]->IsFalse());
 
@@ -3380,27 +3363,12 @@
     context = Handle<Context>(Top::context()->global_context());
   }
 
-  // Compile eval() source.
-  bool is_global_context = context->IsGlobalContext();
-  Handle<String> source(String::cast(args[0]));
-  Object* obj = Heap::LookupEvalCache(is_global_context, *source);
-  if (obj->IsFailure()) return obj;
 
-  Handle<JSFunction> boilerplate;
-  if (!obj->IsJSFunction()) {
-    Counters::eval_cache_misses.Increment();
-    boilerplate = Compiler::CompileEval(is_global_context, source);
-    if (boilerplate.is_null()) return Failure::Exception();
-
-    Object* obj =
-        Heap::PutInEvalCache(is_global_context, *source, *boilerplate);
-    if (obj->IsFailure()) return obj;
-
-  } else {
-    Counters::eval_cache_hits.Increment();
-    boilerplate = Handle<JSFunction>(JSFunction::cast(obj));
-  }
-
+  // Compile source string.
+  bool is_global = context->IsGlobalContext();
+  Handle<JSFunction> boilerplate =
+      Compiler::CompileEval(is_global, source);
+  if (boilerplate.is_null()) return Failure::Exception();
   Handle<JSFunction> fun =
       Factory::NewFunctionFromBoilerplate(boilerplate, context);
   return *fun;
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index b51cb98..64706b5 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -484,10 +484,13 @@
   ASSERT(name->IsSymbol());
   if (code->sinfo_size() > 0) {
     Object** p = &Memory::Object_at(code->sinfo_start());
-    if (*p++ == name) {
-      int n;
-      ReadInt(p, &n);  // n = number of context slots
-      return n -1;  // the function context slot is the last entry
+    if (*p == name) {
+      p = ContextEntriesAddr(code);
+      int n;  // number of context slots
+      ReadInt(p, &n);
+      ASSERT(n != 0);
+      // The function context slot is the last entry.
+      return n + Context::MIN_CONTEXT_SLOTS - 1;
     }
   }
   return -1;
diff --git a/src/scopes.cc b/src/scopes.cc
index 96f0c60..88a6820 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -826,8 +826,6 @@
 }
 
 
-DECLARE_bool(usage_computation);
-
 void Scope::AllocateNonParameterLocals() {
   // Each variable occurs exactly once in the locals_ list; all
   // variables that have no rewrite yet are non-parameter locals.
diff --git a/src/serialize.cc b/src/serialize.cc
index ba18ce8..b26e262 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -41,12 +41,6 @@
 
 namespace v8 { namespace internal {
 
-#ifdef DEBUG
-DEFINE_bool(debug_serialization, false,
-            "write debug information into the snapshot.");
-#endif
-
-
 // Encoding: a RelativeAddress must be able to fit in a pointer:
 // it is encoded as an Address with (from MS to LS bits):
 // 27 bits identifying a word in the space, in one of three formats:
@@ -458,7 +452,7 @@
   // Define all entries in the table.
 
   // Builtins
-#define DEF_ENTRY_C(name, ignore) \
+#define DEF_ENTRY_C(name) \
   Add(Builtins::c_function_address(Builtins::c_##name), \
       C_BUILTIN, \
       Builtins::c_##name, \
@@ -467,12 +461,12 @@
   BUILTIN_LIST_C(DEF_ENTRY_C)
 #undef DEF_ENTRY_C
 
-#define DEF_ENTRY_C(name, ignore) \
+#define DEF_ENTRY_C(name) \
   Add(Builtins::builtin_address(Builtins::name), \
       BUILTIN, \
       Builtins::name, \
       "Builtins::" #name);
-#define DEF_ENTRY_A(name, kind, state) DEF_ENTRY_C(name, _)
+#define DEF_ENTRY_A(name, kind, state) DEF_ENTRY_C(name)
 
   BUILTIN_LIST_C(DEF_ENTRY_C)
   BUILTIN_LIST_A(DEF_ENTRY_A)
@@ -511,12 +505,12 @@
   const char* debug_register_format = "Debug::register_address(%i)";
   size_t dr_format_length = strlen(debug_register_format);
   for (int i = 0; i < kNumJSCallerSaved; ++i) {
-    char* name = NewArray<char>(dr_format_length + 1);
-    OS::SNPrintF(name, dr_format_length, debug_register_format, i);
+    Vector<char> name = Vector<char>::New(dr_format_length + 1);
+    OS::SNPrintF(name, debug_register_format, i);
     Add(Debug_Address(Debug::k_register_address, i).address(),
         DEBUG_ADDRESS,
         Debug::k_register_address << kDebugIdShift | i,
-        name);
+        name.start());
   }
 
   // Stat counters
@@ -534,9 +528,10 @@
   const char* top_address_format = "Top::get_address_from_id(%i)";
   size_t top_format_length = strlen(top_address_format);
   for (uint16_t i = 0; i < Top::k_top_address_count; ++i) {
-    char* name = NewArray<char>(top_format_length + 1);
-    OS::SNPrintF(name, top_format_length, top_address_format, i);
-    Add(Top::get_address_from_id((Top::AddressId)i), TOP_ADDRESS, i, name);
+    Vector<char> name = Vector<char>::New(top_format_length + 1);
+    const char* chars = name.start();
+    OS::SNPrintF(name, top_address_format, i);
+    Add(Top::get_address_from_id((Top::AddressId)i), TOP_ADDRESS, i, chars);
   }
 
   // Extensions
@@ -1020,12 +1015,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  DECLARE_bool(log_code);
-  DECLARE_string(logfile);
-#endif
-
-
 void Serializer::PutLog() {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log_code) {
@@ -1300,10 +1289,6 @@
 }
 
 
-DECLARE_bool(use_ic);
-DECLARE_bool(debug_code);
-DECLARE_bool(lazy);
-
 void Deserializer::GetFlags() {
   reader_.ExpectC('F');
   int argc = reader_.GetInt() + 1;
@@ -1316,11 +1301,11 @@
   reader_.ExpectC(']');
   has_log_ = false;
   for (int i = 1; i < argc; i++) {
-    if (strcmp("--log-code", argv[i]) == 0) {
+    if (strcmp("--log_code", argv[i]) == 0) {
       has_log_ = true;
-    } else if (strcmp("--nouse-ic", argv[i]) == 0) {
+    } else if (strcmp("--nouse_ic", argv[i]) == 0) {
       FLAG_use_ic = false;
-    } else if (strcmp("--debug-code", argv[i]) == 0) {
+    } else if (strcmp("--debug_code", argv[i]) == 0) {
       FLAG_debug_code = true;
     } else if (strcmp("--nolazy", argv[i]) == 0) {
       FLAG_lazy = false;
diff --git a/src/simulator-arm.cc b/src/simulator-arm.cc
index b11ffb1..d76957f 100644
--- a/src/simulator-arm.cc
+++ b/src/simulator-arm.cc
@@ -40,11 +40,9 @@
 
 using ::v8::internal::Object;
 using ::v8::internal::PrintF;
-using ::v8:: internal::ReadLine;
-using ::v8:: internal::DeleteArray;
-
-
-DEFINE_bool(trace_sim, false, "trace simulator execution");
+using ::v8::internal::OS;
+using ::v8::internal::ReadLine;
+using ::v8::internal::DeleteArray;
 
 
 // The Debugger class is used by the simulator while debugging simulated ARM
@@ -204,10 +202,11 @@
   while (!done) {
     if (last_pc != sim_->get_pc()) {
       disasm::Disassembler dasm;
-      char buffer[256];  // use a reasonably large buffer
-      dasm.InstructionDecode(buffer, sizeof(buffer),
+      // use a reasonably large buffer
+      v8::internal::EmbeddedVector<char, 256> buffer;
+      dasm.InstructionDecode(buffer,
                              reinterpret_cast<byte*>(sim_->get_pc()));
-      PrintF("  0x%x  %s\n", sim_->get_pc(), buffer);
+      PrintF("  0x%x  %s\n", sim_->get_pc(), buffer.start());
       last_pc = sim_->get_pc();
     }
     char* line = ReadLine("sim> ");
@@ -258,7 +257,8 @@
         }
       } else if (strcmp(cmd, "disasm") == 0) {
         disasm::Disassembler dasm;
-        char buffer[256];  // use a reasonably large buffer
+        // use a reasonably large buffer
+        v8::internal::EmbeddedVector<char, 256> buffer;
 
         byte* cur = NULL;
         byte* end = NULL;
@@ -283,8 +283,8 @@
         }
 
         while (cur < end) {
-          dasm.InstructionDecode(buffer, sizeof(buffer), cur);
-          PrintF("  0x%x  %s\n", cur, buffer);
+          dasm.InstructionDecode(buffer, cur);
+          PrintF("  0x%x  %s\n", cur, buffer.start());
           cur += Instr::kInstrSize;
         }
       } else if (strcmp(cmd, "gdb") == 0) {
@@ -1339,13 +1339,13 @@
     dbg.Stop(instr);
     return;
   }
-  if (FLAG_trace_sim) {
+  if (::v8::internal::FLAG_trace_sim) {
     disasm::Disassembler dasm;
-    char buffer[256];  // use a reasonably large buffer
+    // use a reasonably large buffer
+    v8::internal::EmbeddedVector<char, 256> buffer;
     dasm.InstructionDecode(buffer,
-                           sizeof(buffer),
                            reinterpret_cast<byte*>(instr));
-    PrintF("  0x%x  %s\n", instr, buffer);
+    PrintF("  0x%x  %s\n", instr, buffer.start());
   }
   if (ConditionallyExecute(instr)) {
     switch (instr->TypeField()) {
@@ -1390,24 +1390,35 @@
 }
 
 
-DEFINE_int(stop_sim_at, -1, "Simulator stop after x number of instructions");
-
-
 //
 void Simulator::execute() {
   // Get the PC to simulate. Cannot use the accessor here as we need the
   // raw PC value and not the one used as input to arithmetic instructions.
   int program_counter = get_pc();
-  while (program_counter != end_sim_pc) {
-    Instr* instr = reinterpret_cast<Instr*>(program_counter);
-    icount_++;
-    if (icount_ == FLAG_stop_sim_at) {
-      Debugger dbg(this);
-      dbg.Debug();
-    } else {
+
+  if (::v8::internal::FLAG_stop_sim_at == 0) {
+    // Fast version of the dispatch loop without checking whether the simulator
+    // should be stopping at a particular executed instruction.
+    while (program_counter != end_sim_pc) {
+      Instr* instr = reinterpret_cast<Instr*>(program_counter);
+      icount_++;
       InstructionDecode(instr);
+      program_counter = get_pc();
     }
-    program_counter = get_pc();
+  } else {
+    // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
+    // we reach the particular instuction count.
+    while (program_counter != end_sim_pc) {
+      Instr* instr = reinterpret_cast<Instr*>(program_counter);
+      icount_++;
+      if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
+        Debugger dbg(this);
+        dbg.Debug();
+      } else {
+        InstructionDecode(instr);
+      }
+      program_counter = get_pc();
+    }
   }
 }
 
diff --git a/src/smart-pointer.h b/src/smart-pointer.h
index accbe03..03fd229 100644
--- a/src/smart-pointer.h
+++ b/src/smart-pointer.h
@@ -31,19 +31,18 @@
 namespace v8 { namespace internal {
 
 
-// A 'scoped pointer' that calls delete[] on its pointer when the
+// A 'scoped array pointer' that calls DeleteArray on its pointer when the
 // destructor is called.
 template<typename T>
 class SmartPointer {
  public:
+
+  // Default constructor. Construct an empty scoped pointer.
+  inline SmartPointer() : p(NULL) {}
+
+
   // Construct a scoped pointer from a plain one.
-  inline SmartPointer(T* pointer) : p(pointer) {}
-
-
-  // When the destructor of the scoped pointer is executed the plain pointer
-  // is deleted using DeleteArray.  This implies that you must allocate with
-  // NewArray.
-  inline ~SmartPointer() { if (p) DeleteArray(p); }
+  explicit inline SmartPointer(T* pointer) : p(pointer) {}
 
 
   // Copy constructor removes the pointer from the original to avoid double
@@ -53,13 +52,20 @@
   }
 
 
+  // When the destructor of the scoped pointer is executed the plain pointer
+  // is deleted using DeleteArray.  This implies that you must allocate with
+  // NewArray.
+  inline ~SmartPointer() { if (p) DeleteArray(p); }
+
+
   // You can get the underlying pointer out with the * operator.
   inline T* operator*() { return p; }
 
 
-  // You can use -> as if it was a plain pointer.
-  inline T* operator->() { return p; }
-
+  // You can use [n] to index as if it was a plain pointer
+  inline T& operator[](size_t i) {
+    return p[i];
+  }
 
   // We don't have implicit conversion to a T* since that hinders migration:
   // You would not be able to change a method from returning a T* to
@@ -81,8 +87,9 @@
   // double freeing.
   inline SmartPointer& operator=(const SmartPointer<T>& rhs) {
     ASSERT(p == NULL);
-    p = rhs.p;
+    T* tmp = rhs.p;  // swap to handle self-assignment
     const_cast<SmartPointer<T>&>(rhs).p = NULL;
+    p = tmp;
     return *this;
   }
 
diff --git a/src/spaces.cc b/src/spaces.cc
index 7920187..e8f460c 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -33,17 +33,6 @@
 
 namespace v8 { namespace internal {
 
-#ifdef DEBUG
-DECLARE_bool(heap_stats);
-DEFINE_bool(collect_heap_spill_statistics, false,
-            "report heap spill statistics along with heap_stats "
-            "(requires heap_stats)");
-#endif
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
-DECLARE_bool(log_gc);
-#endif
-
 // For contiguous spaces, top should be in the space (or at the end) and limit
 // should be the end of the space.
 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \
diff --git a/src/string-stream.cc b/src/string-stream.cc
index 55dc402..9ba6d87 100644
--- a/src/string-stream.cc
+++ b/src/string-stream.cc
@@ -106,11 +106,7 @@
       continue;
     }
     // Read this formatting directive into a temporary buffer
-    const int kTempSize = 24;
-    char temp_buffer[kTempSize];
-    // Wrap temp buffer in a vector to get bounds checking in debug
-    // mode
-    Vector<char> temp(temp_buffer, kTempSize);
+    EmbeddedVector<char, 24> temp;
     int format_length = 0;
     // Skip over the whole control character sequence until the
     // format element type
@@ -140,14 +136,9 @@
     }
     case 'i': case 'd': case 'u': case 'x': case 'c': case 'p': {
       int value = current.data_.u_int_;
-      char formatted[kTempSize];
-#ifdef WIN32
-      // This is not my idea of a good time.
-      _snprintf(formatted, kTempSize, temp.start(), value);
-#else
-      snprintf(formatted, kTempSize, temp.start(), value);
-#endif
-      Add(formatted);
+      EmbeddedVector<char, 24> formatted;
+      OS::SNPrintF(formatted, temp.start(), value);
+      Add(formatted.start());
       break;
     }
     default:
diff --git a/src/stub-cache-arm.cc b/src/stub-cache-arm.cc
index f911f4b..a31ff2f 100644
--- a/src/stub-cache-arm.cc
+++ b/src/stub-cache-arm.cc
@@ -154,25 +154,34 @@
 
 
 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) {
+  // ----------- S t a t e -------------
+  //  -- r1: function
+  //  -- lr: return address
+  // -----------------------------------
+
   HandleScope scope;
 
-  // Enter the JS frame but don't add additional arguments.
-  __ EnterJSFrame(0);
+  // Enter an internal frame.
+  __ EnterInternalFrame();
 
-  // Push the function on the stack and call the runtime function.
-  __ ldr(r0, MemOperand(pp, 0));
-  __ push(r0);
+  // Preserve the function.
+  __ push(r1);
+
+  // Push the function on the stack as the argument to the runtime function.
+  __ push(r1);
   __ CallRuntime(Runtime::kLazyCompile, 1);
 
-  // Move result to r1 and restore number of arguments.
-  __ mov(r1, Operand(r0));
-  __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kArgsLengthOffset));
+  // Calculate the entry point.
+  __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag));
 
-  __ ExitJSFrame(DO_NOT_RETURN);
+  // Restore saved function.
+  __ pop(r1);
+
+  // Tear down temporary frame.
+  __ ExitInternalFrame();
 
   // Do a tail-call of the compiled function.
-  __ add(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag));
-  __ Jump(r1);
+  __ Jump(r2);
 
   return GetCodeWithFlags(flags);
 }
@@ -202,30 +211,23 @@
 
   // Get the properties array of the holder and get the function from the field.
   int offset = index * kPointerSize + Array::kHeaderSize;
-  __ ldr(r3, FieldMemOperand(reg, JSObject::kPropertiesOffset));
-  __ ldr(r3, FieldMemOperand(r3, offset));
+  __ ldr(r1, FieldMemOperand(reg, JSObject::kPropertiesOffset));
+  __ ldr(r1, FieldMemOperand(r1, offset));
 
   // Check that the function really is a function.
-  __ tst(r3, Operand(kSmiTagMask));
+  __ tst(r1, Operand(kSmiTagMask));
   __ b(eq, &miss);
   // Get the map.
-  __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
+  __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
   __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
   __ cmp(r2, Operand(JS_FUNCTION_TYPE));
   __ b(ne, &miss);
 
-  // TODO(1233523): remove r0 after changing Jump to InvokeCode
-  // Setup argument length register.
-  __ mov(r0, Operand(argc));
   // Patch the function on the stack; 1 ~ receiver.
-  __ str(r3, MemOperand(sp, (argc + 1) * kPointerSize));
+  __ str(r1, MemOperand(sp, (argc + 1) * kPointerSize));
 
-  // Setup the context and jump to the call code of the function (tail call).
-  __ ldr(cp, FieldMemOperand(r3, JSFunction::kContextOffset));
-  __ ldr(r2, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
-  __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset));
-  __ add(r2, r2, Operand(Code::kHeaderSize - kHeapObjectTag));
-  __ Jump(r2);
+  // Invoke the function.
+  __ InvokeFunction(r1, arguments(), JUMP_FUNCTION);
 
   // Handle call cache miss.
   __ bind(&miss);
@@ -330,11 +332,11 @@
   }
 
   // Get the function and setup the context.
-  __ mov(r3, Operand(Handle<JSFunction>(function)));
-  __ ldr(cp, FieldMemOperand(r3, JSFunction::kContextOffset));
+  __ mov(r1, Operand(Handle<JSFunction>(function)));
+  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
 
   // Patch the function on the stack; 1 ~ receiver.
-  __ str(r3, MemOperand(sp, (argc + 1) * kPointerSize));
+  __ str(r1, MemOperand(sp, (argc + 1) * kPointerSize));
 
   // Jump to the cached code (tail call).
   Handle<Code> code(function->code());
diff --git a/src/stub-cache-ia32.cc b/src/stub-cache-ia32.cc
index 89dccbe..fb2ff11 100644
--- a/src/stub-cache-ia32.cc
+++ b/src/stub-cache-ia32.cc
@@ -467,7 +467,7 @@
   HandleScope scope;
 
   // Enter an internal frame.
-  __ EnterFrame(StackFrame::INTERNAL);
+  __ EnterInternalFrame();
 
   // Push a copy of the function onto the stack.
   __ push(edi);
@@ -476,7 +476,7 @@
   __ CallRuntime(Runtime::kLazyCompile, 1);
   __ pop(edi);
 
-  __ ExitFrame(StackFrame::INTERNAL);
+  __ ExitInternalFrame();
 
   // Do a tail-call of the compiled function.
   __ lea(ecx, FieldOperand(eax, Code::kHeaderSize));
@@ -666,7 +666,7 @@
       __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss);
 
   // Enter an internal frame.
-  __ EnterFrame(StackFrame::INTERNAL);
+  __ EnterInternalFrame();
 
   // Push arguments on the expression stack.
   __ push(edx);  // receiver
@@ -687,7 +687,7 @@
   __ mov(edx, Operand(ebp, (argc + 2) * kPointerSize));  // receiver
 
   // Exit frame.
-  __ ExitFrame(StackFrame::INTERNAL);
+  __ ExitInternalFrame();
 
   // Check that the function really is a function.
   __ test(edi, Immediate(kSmiTagMask));
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 84272a2..8d7c395 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -912,7 +912,6 @@
 }
 
 
-DECLARE_bool(print_code_stubs);
 Object* StubCompiler::GetCodeWithFlags(Code::Flags flags) {
   CodeDesc desc;
   masm_.GetCode(&desc);
diff --git a/src/top.cc b/src/top.cc
index 061b300..2320895 100644
--- a/src/top.cc
+++ b/src/top.cc
@@ -36,11 +36,6 @@
 
 namespace v8 { namespace internal {
 
-DEFINE_bool(trace_exception, false,
-            "print stack trace when throwing exceptions");
-DEFINE_bool(preallocate_message_memory, false,
-            "preallocate some memory to build stack traces.");
-
 ThreadLocalTop Top::thread_local_;
 Mutex* Top::break_access_ = OS::CreateMutex();
 StackFrame::Id Top::break_frame_id_;
@@ -124,11 +119,11 @@
   // When the thread starts running it will allocate a fixed number of bytes
   // on the stack and publish the location of this memory for others to use.
   void Run() {
-    char local_buffer[16 * 1024];
+    EmbeddedVector<char, 16 * 1024> local_buffer;
 
     // Initialize the buffer with a known good value.
-    strncpy(local_buffer, "Trace data was not generated.\n",
-            sizeof(local_buffer));
+    OS::StrNCpy(local_buffer, "Trace data was not generated.\n",
+                local_buffer.length());
 
     // Publish the local buffer and signal its availability.
     data_ = &local_buffer[0];
@@ -142,8 +137,8 @@
 
     // Make sure we access the buffer after the wait to remove all possibility
     // of it being optimized away.
-    strncpy(local_buffer, "PreallocatedMemoryThread shutting down.\n",
-            sizeof(local_buffer));
+    OS::StrNCpy(local_buffer, "PreallocatedMemoryThread shutting down.\n",
+                local_buffer.length());
   }
 
   static char* data() {
@@ -621,9 +616,6 @@
 }
 
 
-// TODO(1233523): Get rid of this hackish abstraction once all
-// JavaScript frames have a function associated with them.
-
 // NOTE: The stack trace frame iterator is an iterator that only
 // traverse proper JavaScript frames; that is JavaScript frames that
 // have proper JavaScript functions. This excludes the problematic
diff --git a/src/usage-analyzer.cc b/src/usage-analyzer.cc
index 0f234d8..2910fc6 100644
--- a/src/usage-analyzer.cc
+++ b/src/usage-analyzer.cc
@@ -33,8 +33,6 @@
 
 namespace v8 { namespace internal {
 
-DEFINE_bool(usage_computation, true, "compute variable usage counts");
-
 // Weight boundaries
 static const int MinWeight = 1;
 static const int MaxWeight = 1000000;
diff --git a/src/utils.cc b/src/utils.cc
index 8cfa237..9310301 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -155,7 +155,7 @@
                         int* size,
                         int extra_space,
                         bool verbose) {
-  FILE* file = fopen(filename, "rb");
+  FILE* file = OS::FOpen(filename, "rb");
   if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
     if (verbose) {
       OS::PrintError("Cannot read from file %s.\n", filename);
@@ -220,7 +220,7 @@
                const char* str,
                int size,
                bool verbose) {
-  FILE* f = fopen(filename, "wb");
+  FILE* f = OS::FOpen(filename, "wb");
   if (f == NULL) {
     if (verbose) {
       OS::PrintError("Cannot open file %s for reading.\n", filename);
@@ -234,8 +234,7 @@
 
 
 StringBuilder::StringBuilder(int size) {
-  buffer_ = NewArray<char>(size);
-  size_ = size;
+  buffer_ = Vector<char>::New(size);
   position_ = 0;
 }
 
@@ -246,7 +245,7 @@
 
 
 void StringBuilder::AddSubstring(const char* s, int n) {
-  ASSERT(!is_finalized() && position_ + n < size_);
+  ASSERT(!is_finalized() && position_ + n < buffer_.length());
   ASSERT(static_cast<size_t>(n) <= strlen(s));
   memcpy(&buffer_[position_], s, n * kCharSize);
   position_ += n;
@@ -254,14 +253,13 @@
 
 
 void StringBuilder::AddFormatted(const char* format, ...) {
-  ASSERT(!is_finalized() && position_ < size_);
+  ASSERT(!is_finalized() && position_ < buffer_.length());
   va_list args;
   va_start(args, format);
-  int remaining = size_ - position_;
-  int n = OS::VSNPrintF(&buffer_[position_], remaining, format, args);
+  int n = OS::VSNPrintF(buffer_ + position_, format, args);
   va_end(args);
-  if (n < 0 || n >= remaining) {
-    position_ = size_;
+  if (n < 0 || n >= (buffer_.length() - position_)) {
+    position_ = buffer_.length();
   } else {
     position_ += n;
   }
@@ -276,14 +274,14 @@
 
 
 char* StringBuilder::Finalize() {
-  ASSERT(!is_finalized() && position_ < size_);
+  ASSERT(!is_finalized() && position_ < buffer_.length());
   buffer_[position_] = '\0';
   // Make sure nobody managed to add a 0-character to the
   // buffer while building the string.
-  ASSERT(strlen(buffer_) == static_cast<size_t>(position_));
+  ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
   position_ = -1;
   ASSERT(is_finalized());
-  return buffer_;
+  return buffer_.start();
 }
 
 } }  // namespace v8::internal
diff --git a/src/utils.h b/src/utils.h
index 1c07ba4..1f38525 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -279,6 +279,10 @@
     ASSERT(length == 0 || (length > 0 && data != NULL));
   }
 
+  static Vector<T> New(int length) {
+    return Vector<T>(NewArray<T>(length), length);
+  }
+
   // Returns the length of the vector.
   int length() const { return length_; }
 
@@ -310,6 +314,11 @@
     length_ = 0;
   }
 
+  inline Vector<T> operator+(int offset) {
+    ASSERT(offset < length_);
+    return Vector<T>(start_ + offset, length_ - offset);
+  }
+
   // Factory method for creating empty vectors.
   static Vector<T> empty() { return Vector<T>(NULL, 0); }
 
@@ -319,6 +328,15 @@
 };
 
 
+template <typename T, int kSize>
+class EmbeddedVector : public Vector<T> {
+ public:
+  EmbeddedVector() : Vector<T>(buffer_, kSize) { }
+ private:
+  T buffer_[kSize];
+};
+
+
 inline Vector<const char> CStrVector(const char* data) {
   return Vector<const char>(data, strlen(data));
 }
@@ -327,6 +345,11 @@
   return Vector<char>(data, strlen(data));
 }
 
+inline Vector<char> MutableCStrVector(char* data, int max) {
+  int length = strlen(data);
+  return Vector<char>(data, (length < max) ? length : max);
+}
+
 template <typename T>
 inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
                                              int length) {
@@ -369,11 +392,11 @@
   explicit StringBuilder(int size);
 
   StringBuilder(char* buffer, int size)
-      : buffer_(buffer), size_(size), position_(0) { }
+      : buffer_(buffer, size), position_(0) { }
 
   ~StringBuilder() { if (!is_finalized()) Finalize(); }
 
-  int size() const { return size_; }
+  int size() const { return buffer_.length(); }
 
   // Get the current position in the builder.
   int position() const {
@@ -389,7 +412,7 @@
   // instead.
   void AddCharacter(char c) {
     ASSERT(c != '\0');
-    ASSERT(!is_finalized() && position_ < size_);
+    ASSERT(!is_finalized() && position_ < buffer_.length());
     buffer_[position_++] = c;
   }
 
@@ -412,8 +435,7 @@
   char* Finalize();
 
  private:
-  char* buffer_;
-  int size_;
+  Vector<char> buffer_;
   int position_;
 
   bool is_finalized() const { return position_ < 0; }
diff --git a/src/v8-counters.cc b/src/v8-counters.cc
index f6b1c3d..95847f6 100644
--- a/src/v8-counters.cc
+++ b/src/v8-counters.cc
@@ -31,17 +31,24 @@
 
 namespace v8 { namespace internal {
 
-#define SR(name, caption) StatsRate Counters::name(L###caption, k_##name);
+#define SR(name, caption) \
+  StatsRate Counters::name = { \
+  { { L"t:" L###caption, NULL, false }, 0, 0 }, \
+  { L"c:" L###caption, NULL, false } };
+
   STATS_RATE_LIST(SR)
 #undef SR
 
-#define SC(name, caption) StatsCounter Counters::name(L###caption, k_##name);
+#define SC(name, caption) \
+  StatsCounter Counters::name = { L"c:" L###caption, NULL, false };
+
   STATS_COUNTER_LIST_1(SC)
   STATS_COUNTER_LIST_2(SC)
 #undef SC
 
-StatsCounter Counters::state_counters[state_tag_count] = {
-#define COUNTER_NAME(name) StatsCounter(L"V8.State" L###name, k_##name),
+StatsCounter Counters::state_counters[] = {
+#define COUNTER_NAME(name) \
+  { L"c:V8.State" L###name, NULL, false },
   STATE_TAG_LIST(COUNTER_NAME)
 #undef COUNTER_NAME
 };
diff --git a/src/v8-counters.h b/src/v8-counters.h
index 76c2ec8..9819cdc 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -71,8 +71,8 @@
   SC(call_normal_stubs, V8.CallNormalStubs)                      \
   SC(call_megamorphic_stubs, V8.CallMegamorphicStubs)            \
   SC(arguments_adaptors, V8.ArgumentsAdaptors)                   \
-  SC(eval_cache_hits, V8.EvalCacheHits)                          \
-  SC(eval_cache_misses, V8.EvalCacheMisses)                      \
+  SC(compilation_cache_hits, V8.CompilationCacheHits)            \
+  SC(compilation_cache_misses, V8.CompilationCacheMisses)        \
   /* Amount of evaled source code. */                            \
   SC(total_eval_size, V8.TotalEvalSize)                          \
   /* Amount of loaded source code. */                            \
@@ -122,11 +122,13 @@
 // This file contains all the v8 counters that are in use.
 class Counters : AllStatic {
  public:
-#define SR(name, caption) static StatsRate name;
+#define SR(name, caption) \
+  static StatsRate name;
   STATS_RATE_LIST(SR)
 #undef SR
 
-#define SC(name, caption) static StatsCounter name;
+#define SC(name, caption) \
+  static StatsCounter name;
   STATS_COUNTER_LIST_1(SC)
   STATS_COUNTER_LIST_2(SC)
 #undef SC
diff --git a/src/v8.cc b/src/v8.cc
index 4a7dc6f..29013fd 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -34,9 +34,6 @@
 
 namespace v8 { namespace internal {
 
-DEFINE_bool(preemption, false,
-            "activate a 100ms timer that switches between V8 threads");
-
 bool V8::has_been_setup_ = false;
 bool V8::has_been_disposed_ = false;
 
diff --git a/src/v8.h b/src/v8.h
index acdb119..328c88c 100644
--- a/src/v8.h
+++ b/src/v8.h
@@ -53,7 +53,7 @@
 #include "checks.h"
 #include "allocation.h"
 #include "utils.h"
-#include "flags-inl.h"
+#include "flags.h"
 
 // Objects & heap
 #include "objects.h"
diff --git a/src/v8natives.js b/src/v8natives.js
index d59cc4b..afd67fd 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -414,107 +414,3 @@
 };
 
 %SetCode($Function, NewFunction);
-
-
-// NOTE: The following functions (call and apply) are only used in this
-// form on the ARM platform. On IA-32 they are handled through specialized
-// builtins; see builtins-ia32.cc.
-
-%AddProperty($Function.prototype, "call", function(receiver) {
-  // Make sure the receiver of this call is a function. If it isn't
-  // we "fake" a call of it (without the right arguments) to force
-  // an exception to be thrown.
-  if (!IS_FUNCTION(this)) this();
-
-  // If receiver is null or undefined set the receiver to the global
-  // object. If the receiver isn't an object, we convert the
-  // receiver to an object.
-  if (receiver == null) receiver = global;
-  else if (!IS_OBJECT(receiver)) receiver = ToObject(receiver);
-
-  %_SetThisFunction(this);
-  %_SetThis(receiver);
-
-  var len = %_GetArgumentsLength(1);
-  return %_ShiftDownAndTailCall(len ? len - 1 : 0);
-}, DONT_ENUM);
-
-
-// This implementation of Function.prototype.apply replaces the stack frame
-// of the apply call with the new stack frame containing the arguments from
-// the args array.
-%AddProperty($Function.prototype, "apply", function(receiver, args) {
-  var length = (args == null) ? 0 : ToUint32(args.length);
-
-  // We can handle any number of apply arguments if the stack is
-  // big enough, but sanity check the value to avoid overflow when
-  // multiplying with pointer size.
-  if (length > 0x800000) {
-    throw new $RangeError(
-        "Function.prototype.apply cannot support " + length + " arguments.");
-  }
-
-  if (!IS_FUNCTION(this)) {
-    throw new $TypeError('Function.prototype.apply was called on ' + this.toString() + ', which is a ' + (typeof this) + ' and not a function');
-  }
-
-  // Make sure args has the right type.
-  if (args != null && %ClassOf(args) !== 'Array' && %ClassOf(args) !== 'Arguments') {
-    throw new $TypeError('Function.prototype.apply: args has wrong type');
-  }
-
-  // If receiver is null or undefined set the receiver to the global
-  // object. If the receiver isn't an object, we convert the
-  // receiver to an object.
-  if (receiver == null) receiver = global;
-  else if (!IS_OBJECT(receiver)) receiver = ToObject(receiver);
-
-  %_SetThisFunction(this);
-  %_SetThis(receiver);
-
-  var arguments_length = %_GetArgumentsLength(2);
-
-  // This method has 2 formal arguments so if less are passed, then space has
-  // been made.
-  if (arguments_length < 2)
-    arguments_length = 2;
-
-  // Move some stuff to locals so they don't get overwritten when we start
-  // expanding the args array.
-  var saved_args = args;
-
-  if (arguments_length > length) {
-    // We have too many arguments - we need to squash the frame.
-    %_SquashFrame(arguments_length, length);
-  } else if (arguments_length != length) {
-    // We have too few spaces for arguments - we need to expand the frame.
-    if (!%_ExpandFrame(arguments_length, length)) {
-      throw new $RangeError(
-          "Function.prototype.apply cannot find stack space for " + length + " arguments.");
-    }
-    // GC doesn't like junk in the arguments!
-    for (var i = 0; i < length; i++) {
-      %_SetArgument(i, 0, length);
-    }
-  }
-
-  // Update-number-of-arguments field to keep things looking consistent for
-  // stack traces, and uses of arguments or arguments.length.
-  %_SetArgumentsLength(length);
-
-  // NOTE: For the fast case this should be implemented in assembler,
-  // which would allow us to omit bounds and class checks galore.  The
-  // assembler version could fall back to this implementation if
-  // tricky stuff is found, like arrays implemented as dictionaries or
-  // holes in arrays.
-  for (var i = 0; i < length; i++) {
-    %_SetArgument(i, saved_args[i], length);
-  }
-
-  // Replaces the current frame with the new call.  This has the added effect
-  // of removing apply from the stack trace entirely, which matches the
-  // behaviour of Firefox.
-  return %_TailCallWithArguments(length);
-}, DONT_ENUM);
-
-
diff --git a/test/cctest/cctest.cc b/test/cctest/cctest.cc
index 6591f17..e9c8f0d 100644
--- a/test/cctest/cctest.cc
+++ b/test/cctest/cctest.cc
@@ -44,9 +44,9 @@
     basename = strrchr(const_cast<char *>(file), '\\');
   }
   if (!basename) {
-    basename = strdup(file);
+    basename = v8::internal::OS::StrDup(file);
   } else {
-    basename = strdup(basename + 1);
+    basename = v8::internal::OS::StrDup(basename + 1);
   }
   // Drop the extension, if there is one.
   char *extension = strrchr(basename, '.');
@@ -77,7 +77,7 @@
       print_run_count = false;
 
     } else {
-      char* arg_copy = strdup(arg);
+      char* arg_copy = v8::internal::OS::StrDup(arg);
       char* testname = strchr(arg_copy, '/');
       if (testname) {
         // Split the string in two by nulling the slash and then run
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index f43a319..800cc8b 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -1427,14 +1427,14 @@
 
 // These tests run for a long time and prevent us from running tests
 // that come after them so they cannot run in parallel.
-DISABLED_TEST(OutOfMemory) {
+TEST(OutOfMemory) {
   // It's not possible to read a snapshot into a heap with different dimensions.
   if (v8::internal::Snapshot::IsEnabled()) return;
   // Set heap limits.
   static const int K = 1024;
   v8::ResourceConstraints constraints;
   constraints.set_max_young_space_size(256 * K);
-  constraints.set_max_old_space_size(2 * K * K);
+  constraints.set_max_old_space_size(4 * K * K);
   v8::SetResourceConstraints(&constraints);
 
   // Execute a script that causes out of memory.
@@ -1468,14 +1468,14 @@
 }
 
 
-DISABLED_TEST(OutOfMemoryNested) {
+TEST(OutOfMemoryNested) {
   // It's not possible to read a snapshot into a heap with different dimensions.
   if (v8::internal::Snapshot::IsEnabled()) return;
   // Set heap limits.
   static const int K = 1024;
   v8::ResourceConstraints constraints;
   constraints.set_max_young_space_size(256 * K);
-  constraints.set_max_old_space_size(2 * K * K);
+  constraints.set_max_old_space_size(4 * K * K);
   v8::SetResourceConstraints(&constraints);
 
   v8::HandleScope scope;
@@ -4480,15 +4480,11 @@
 }
 
 
-DECLARE_int(prng_seed);
-DEFINE_int(prng_seed, 42, "Seed used for threading test randomness");
-
-
 static unsigned linear_congruential_generator;
 
 
 void ApiTestFuzzer::Setup(PartOfTest part) {
-  linear_congruential_generator = FLAG_prng_seed;
+  linear_congruential_generator = i::FLAG_testing_prng_seed;
   fuzzing_ = true;
   int start = (part == FIRST_PART) ? 0 : (RegisterThreadedTest::count() >> 1);
   int end = (part == FIRST_PART)
@@ -4697,7 +4693,7 @@
 }
 
 
-static void EnsureNoSurvivingGlobalObjects() {
+static int GetSurvivingGlobalObjectsCount() {
   int count = 0;
   v8::internal::Heap::CollectAllGarbage();
   v8::internal::HeapIterator it;
@@ -4710,38 +4706,34 @@
 #ifdef DEBUG
   if (count > 0) v8::internal::Heap::TracePathToGlobal();
 #endif
-  CHECK_EQ(0, count);
+  return count;
 }
 
 
-// This test assumes that there are zero global objects when the
-// test starts.  This is not going to be true if we are using the
-// API fuzzer.
 TEST(DontLeakGlobalObjects) {
   // Regression test for issues 1139850 and 1174891.
 
-  v8::internal::V8::Initialize(NULL);
-  if (v8::internal::Snapshot::IsEnabled()) return;
+  v8::V8::Initialize();
 
-  EnsureNoSurvivingGlobalObjects();
+  int count = GetSurvivingGlobalObjectsCount();
 
   for (int i = 0; i < 5; i++) {
     { v8::HandleScope scope;
       LocalContext context;
     }
-    EnsureNoSurvivingGlobalObjects();
+    CHECK_EQ(count, GetSurvivingGlobalObjectsCount());
 
     { v8::HandleScope scope;
       LocalContext context;
       v8_compile("Date")->Run();
     }
-    EnsureNoSurvivingGlobalObjects();
+    CHECK_EQ(count, GetSurvivingGlobalObjectsCount());
 
     { v8::HandleScope scope;
       LocalContext context;
       v8_compile("/aaa/")->Run();
     }
-    EnsureNoSurvivingGlobalObjects();
+    CHECK_EQ(count, GetSurvivingGlobalObjectsCount());
 
     { v8::HandleScope scope;
       const char* extension_list[] = { "v8/gc" };
@@ -4749,7 +4741,7 @@
       LocalContext context(&extensions);
       v8_compile("gc();")->Run();
     }
-    EnsureNoSurvivingGlobalObjects();
+    CHECK_EQ(count, GetSurvivingGlobalObjectsCount());
 
     { v8::HandleScope scope;
       const char* extension_list[] = { "v8/print" };
@@ -4757,14 +4749,13 @@
       LocalContext context(&extensions);
       v8_compile("print('hest');")->Run();
     }
-    EnsureNoSurvivingGlobalObjects();
+    CHECK_EQ(count, GetSurvivingGlobalObjectsCount());
   }
 }
 
 
 THREADED_TEST(CheckForCrossContextObjectLiterals) {
-  v8::internal::V8::Initialize(NULL);
-  if (v8::internal::Snapshot::IsEnabled()) return;
+  v8::V8::Initialize();
 
   const int nof = 2;
   const char* sources[nof] = {
@@ -4880,7 +4871,7 @@
       "\n"
       "Foo();\n");
   v8::Handle<v8::Script> script =
-    v8::Script::Compile(source, v8::String::New("test.js"));
+      v8::Script::Compile(source, v8::String::New("test.js"));
   v8::TryCatch try_catch;
   v8::Handle<v8::Value> result = script->Run();
   CHECK(result.IsEmpty());
@@ -4897,3 +4888,20 @@
   v8::String::AsciiValue name(message->GetScriptResourceName());
   CHECK_EQ("test.js", *name);
 }
+
+
+THREADED_TEST(CompilationCache) {
+  v8::HandleScope scope;
+  LocalContext context;
+  v8::Handle<v8::String> source0 = v8::String::New("1234");
+  v8::Handle<v8::String> source1 = v8::String::New("1234");
+  v8::Handle<v8::Script> script0 =
+      v8::Script::Compile(source0, v8::String::New("test.js"));
+  v8::Handle<v8::Script> script1 =
+      v8::Script::Compile(source1, v8::String::New("test.js"));
+  v8::Handle<v8::Script> script2 =
+      v8::Script::Compile(source0);  // different origin
+  CHECK_EQ(1234, script0->Run()->Int32Value());
+  CHECK_EQ(1234, script1->Run()->Int32Value());
+  CHECK_EQ(1234, script2->Run()->Int32Value());
+}
diff --git a/test/cctest/test-assembler-arm.cc b/test/cctest/test-assembler-arm.cc
index a02441d..7903fab 100644
--- a/test/cctest/test-assembler-arm.cc
+++ b/test/cctest/test-assembler-arm.cc
@@ -33,14 +33,6 @@
 #include "assembler-arm-inl.h"
 #include "cctest.h"
 
-// The test framework does not accept flags on the command line, so we set them
-namespace v8 { namespace internal {
-  DECLARE_string(natives_file);
-  DECLARE_bool(debug_code);
-  DECLARE_bool(eliminate_jumps);
-  DECLARE_bool(print_jump_elimination);
-} }  // namespace v8::internal
-
 using namespace v8::internal;
 
 
@@ -53,6 +45,7 @@
 static v8::Persistent<v8::Context> env;
 
 
+// The test framework does not accept flags on the command line, so we set them
 static void InitializeVM() {
   // disable compilation of natives by specifying an empty natives file
   FLAG_natives_file = "";
diff --git a/test/cctest/test-compiler.cc b/test/cctest/test-compiler.cc
index dca36e2..38478cf 100644
--- a/test/cctest/test-compiler.cc
+++ b/test/cctest/test-compiler.cc
@@ -77,10 +77,10 @@
 
 static double Inc(int x) {
   const char* source = "result = %d + 1;";
-  char buffer[512];
-  OS::SNPrintF(buffer, sizeof(buffer), source, x);
+  EmbeddedVector<char, 512> buffer;
+  OS::SNPrintF(buffer, source, x);
 
-  Handle<JSFunction> fun = Compile(buffer);
+  Handle<JSFunction> fun = Compile(buffer.start());
   if (fun.is_null()) return -1;
 
   bool has_pending_exception;
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 89fcb36..2720aa8 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -35,6 +35,8 @@
 #include "stub-cache.h"
 #include "cctest.h"
 
+
+using ::v8::internal::EmbeddedVector;
 using ::v8::internal::Object;
 using ::v8::internal::OS;
 using ::v8::internal::Handle;
@@ -52,12 +54,6 @@
 // Size of temp buffer for formatting small strings.
 #define SMALL_STRING_BUFFER_SIZE 80
 
-#ifdef DEBUG
-namespace v8 { namespace internal {
-DECLARE_bool(verify_heap);
-} }
-#endif
-
 // --- A d d i t i o n a l   C h e c k   H e l p e r s
 
 
@@ -203,33 +199,34 @@
 // associated break point number.
 static int SetBreakPointFromJS(const char* function_name,
                                int line, int position) {
-  char buffer[SMALL_STRING_BUFFER_SIZE];
-  OS::SNPrintF(buffer, SMALL_STRING_BUFFER_SIZE,
+  EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
+  OS::SNPrintF(buffer,
                "debug.Debug.setBreakPoint(%s,%d,%d)",
                function_name, line, position);
   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
-  return v8::Script::Compile(v8::String::New(buffer))->Run()->Int32Value();
+  v8::Handle<v8::String> str = v8::String::New(buffer.start());
+  return v8::Script::Compile(str)->Run()->Int32Value();
 }
 
 
 // Set a break point in a script using the global Debug object.
 static int SetScriptBreakPointFromJS(const char* script_data,
                                      int line, int column) {
-  char buffer[SMALL_STRING_BUFFER_SIZE];
+  EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
   if (column >= 0) {
     // Column specified set script break point on precise location.
-    OS::SNPrintF(buffer, SMALL_STRING_BUFFER_SIZE,
+    OS::SNPrintF(buffer,
                  "debug.Debug.setScriptBreakPoint(\"%s\",%d,%d)",
                  script_data, line, column);
   } else {
     // Column not specified set script break point on line.
-    OS::SNPrintF(buffer, SMALL_STRING_BUFFER_SIZE,
+    OS::SNPrintF(buffer,
                  "debug.Debug.setScriptBreakPoint(\"%s\",%d)",
                  script_data, line);
   }
   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
-
-  return v8::Script::Compile(v8::String::New(buffer))->Run()->Int32Value();
+  v8::Handle<v8::String> str = v8::String::New(buffer.start());
+  return v8::Script::Compile(str)->Run()->Int32Value();
 }
 
 
@@ -242,54 +239,54 @@
 
 // Clear a break point using the global Debug object.
 static void ClearBreakPointFromJS(int break_point_number) {
-  char buffer[SMALL_STRING_BUFFER_SIZE];
-  OS::SNPrintF(buffer, SMALL_STRING_BUFFER_SIZE,
+  EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
+  OS::SNPrintF(buffer,
                "debug.Debug.clearBreakPoint(%d)",
                break_point_number);
   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
-  v8::Script::Compile(v8::String::New(buffer))->Run();
+  v8::Script::Compile(v8::String::New(buffer.start()))->Run();
 }
 
 
 static void EnableScriptBreakPointFromJS(int break_point_number) {
-  char buffer[SMALL_STRING_BUFFER_SIZE];
-  OS::SNPrintF(buffer, SMALL_STRING_BUFFER_SIZE,
+  EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
+  OS::SNPrintF(buffer,
                "debug.Debug.enableScriptBreakPoint(%d)",
                break_point_number);
   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
-  v8::Script::Compile(v8::String::New(buffer))->Run();
+  v8::Script::Compile(v8::String::New(buffer.start()))->Run();
 }
 
 
 static void DisableScriptBreakPointFromJS(int break_point_number) {
-  char buffer[SMALL_STRING_BUFFER_SIZE];
-  OS::SNPrintF(buffer, SMALL_STRING_BUFFER_SIZE,
+  EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
+  OS::SNPrintF(buffer,
                "debug.Debug.disableScriptBreakPoint(%d)",
                break_point_number);
   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
-  v8::Script::Compile(v8::String::New(buffer))->Run();
+  v8::Script::Compile(v8::String::New(buffer.start()))->Run();
 }
 
 
 static void ChangeScriptBreakPointConditionFromJS(int break_point_number,
                                                   const char* condition) {
-  char buffer[SMALL_STRING_BUFFER_SIZE];
-  OS::SNPrintF(buffer, SMALL_STRING_BUFFER_SIZE,
+  EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
+  OS::SNPrintF(buffer,
                "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")",
                break_point_number, condition);
   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
-  v8::Script::Compile(v8::String::New(buffer))->Run();
+  v8::Script::Compile(v8::String::New(buffer.start()))->Run();
 }
 
 
 static void ChangeScriptBreakPointIgnoreCountFromJS(int break_point_number,
                                                     int ignoreCount) {
-  char buffer[SMALL_STRING_BUFFER_SIZE];
-  OS::SNPrintF(buffer, SMALL_STRING_BUFFER_SIZE,
+  EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
+  OS::SNPrintF(buffer,
                "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)",
                break_point_number, ignoreCount);
   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
-  v8::Script::Compile(v8::String::New(buffer))->Run();
+  v8::Script::Compile(v8::String::New(buffer.start()))->Run();
 }
 
 
diff --git a/test/cctest/test-disasm-arm.cc b/test/cctest/test-disasm-arm.cc
index f1b43cd..7df292a 100644
--- a/test/cctest/test-disasm-arm.cc
+++ b/test/cctest/test-disasm-arm.cc
@@ -51,17 +51,17 @@
 
 bool DisassembleAndCompare(byte* pc, const char* compare_string) {
   disasm::Disassembler disasm;
-  char disasm_buffer[128];
+  EmbeddedVector<char, 128> disasm_buffer;
 
-  disasm.InstructionDecode(disasm_buffer, sizeof disasm_buffer, pc);
+  disasm.InstructionDecode(disasm_buffer, pc);
 
-  if (strcmp(compare_string, disasm_buffer) != 0) {
+  if (strcmp(compare_string, disasm_buffer.start()) != 0) {
     fprintf(stderr,
             "expected: \n"
             "%s\n"
             "disassembled: \n"
             "%s\n\n",
-            compare_string, disasm_buffer);
+            compare_string, disasm_buffer.start());
     return false;
   }
   return true;
diff --git a/test/cctest/test-flags.cc b/test/cctest/test-flags.cc
index b4827b6..a3aa4b2 100644
--- a/test/cctest/test-flags.cc
+++ b/test/cctest/test-flags.cc
@@ -32,61 +32,54 @@
 
 using namespace v8::internal;
 
-DEFINE_bool(bool_flag, true, "bool_flag");
-DEFINE_int(int_flag, 13, "int_flag");
-DEFINE_float(float_flag, 2.5, "float-flag");
-DEFINE_string(string_flag, "Hello, world!", "string-flag");
-
-
 // This test must be executed first!
 TEST(Default) {
-  CHECK(FLAG_bool_flag);
-  CHECK_EQ(13, FLAG_int_flag);
-  CHECK_EQ(2.5, FLAG_float_flag);
-  CHECK_EQ(0, strcmp(FLAG_string_flag, "Hello, world!"));
+  CHECK(FLAG_testing_bool_flag);
+  CHECK_EQ(13, FLAG_testing_int_flag);
+  CHECK_EQ(2.5, FLAG_testing_float_flag);
+  CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "Hello, world!"));
 }
 
 
 static void SetFlagsToDefault() {
-  for (Flag* f = FlagList::list(); f != NULL; f = f->next()) {
-    f->SetToDefault();
-  }
+  FlagList::ResetAllFlags();
   TestDefault();
 }
 
 
 TEST(Flags1) {
-  FlagList::Print(__FILE__, false);
-  FlagList::Print(NULL, true);
+  FlagList::PrintHelp();
 }
 
 
 TEST(Flags2) {
   SetFlagsToDefault();
   int argc = 7;
-  const char* argv[] = { "Test2", "-nobool-flag", "notaflag", "--int_flag=77",
-                         "-float_flag=.25", "--string_flag", "no way!" };
+  const char* argv[] = { "Test2", "-notesting-bool-flag", "notaflag",
+                         "--testing_int_flag=77", "-testing_float_flag=.25",
+                         "--testing_string_flag", "no way!" };
   CHECK_EQ(0, FlagList::SetFlagsFromCommandLine(&argc,
                                                 const_cast<char **>(argv),
                                                 false));
   CHECK_EQ(7, argc);
-  CHECK(!FLAG_bool_flag);
-  CHECK_EQ(77, FLAG_int_flag);
-  CHECK_EQ(.25, FLAG_float_flag);
-  CHECK_EQ(0, strcmp(FLAG_string_flag, "no way!"));
+  CHECK(!FLAG_testing_bool_flag);
+  CHECK_EQ(77, FLAG_testing_int_flag);
+  CHECK_EQ(.25, FLAG_testing_float_flag);
+  CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "no way!"));
 }
 
 
 TEST(Flags2b) {
   SetFlagsToDefault();
   const char* str =
-      " -nobool-flag notaflag   --int_flag=77 -float_flag=.25  "
-      "--string_flag   no_way!  ";
+      " -notesting-bool-flag notaflag   --testing_int_flag=77 "
+      "-testing_float_flag=.25  "
+      "--testing_string_flag   no_way!  ";
   CHECK_EQ(0, FlagList::SetFlagsFromString(str, strlen(str)));
-  CHECK(!FLAG_bool_flag);
-  CHECK_EQ(77, FLAG_int_flag);
-  CHECK_EQ(.25, FLAG_float_flag);
-  CHECK_EQ(0, strcmp(FLAG_string_flag, "no_way!"));
+  CHECK(!FLAG_testing_bool_flag);
+  CHECK_EQ(77, FLAG_testing_int_flag);
+  CHECK_EQ(.25, FLAG_testing_float_flag);
+  CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "no_way!"));
 }
 
 
@@ -94,36 +87,38 @@
   SetFlagsToDefault();
   int argc = 8;
   const char* argv[] =
-      { "Test3", "--bool_flag", "notaflag", "--int_flag", "-666",
-        "--float_flag", "-12E10", "-string-flag=foo-bar" };
+      { "Test3", "--testing_bool_flag", "notaflag",
+        "--testing_int_flag", "-666",
+        "--testing_float_flag", "-12E10", "-testing-string-flag=foo-bar" };
   CHECK_EQ(0, FlagList::SetFlagsFromCommandLine(&argc,
                                                 const_cast<char **>(argv),
                                                 true));
   CHECK_EQ(2, argc);
-  CHECK(FLAG_bool_flag);
-  CHECK_EQ(-666, FLAG_int_flag);
-  CHECK_EQ(-12E10, FLAG_float_flag);
-  CHECK_EQ(0, strcmp(FLAG_string_flag, "foo-bar"));
+  CHECK(FLAG_testing_bool_flag);
+  CHECK_EQ(-666, FLAG_testing_int_flag);
+  CHECK_EQ(-12E10, FLAG_testing_float_flag);
+  CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "foo-bar"));
 }
 
 
 TEST(Flags3b) {
   SetFlagsToDefault();
   const char* str =
-      "--bool_flag notaflag --int_flag -666 --float_flag -12E10 "
-      "-string-flag=foo-bar";
+      "--testing_bool_flag notaflag --testing_int_flag -666 "
+      "--testing_float_flag -12E10 "
+      "-testing-string-flag=foo-bar";
   CHECK_EQ(0, FlagList::SetFlagsFromString(str, strlen(str)));
-  CHECK(FLAG_bool_flag);
-  CHECK_EQ(-666, FLAG_int_flag);
-  CHECK_EQ(-12E10, FLAG_float_flag);
-  CHECK_EQ(0, strcmp(FLAG_string_flag, "foo-bar"));
+  CHECK(FLAG_testing_bool_flag);
+  CHECK_EQ(-666, FLAG_testing_int_flag);
+  CHECK_EQ(-12E10, FLAG_testing_float_flag);
+  CHECK_EQ(0, strcmp(FLAG_testing_string_flag, "foo-bar"));
 }
 
 
 TEST(Flags4) {
   SetFlagsToDefault();
   int argc = 3;
-  const char* argv[] = { "Test4", "--bool_flag", "--foo" };
+  const char* argv[] = { "Test4", "--testing_bool_flag", "--foo" };
   CHECK_EQ(0, FlagList::SetFlagsFromCommandLine(&argc,
                                                 const_cast<char **>(argv),
                                                 true));
@@ -133,7 +128,7 @@
 
 TEST(Flags4b) {
   SetFlagsToDefault();
-  const char* str = "--bool_flag --foo";
+  const char* str = "--testing_bool_flag --foo";
   CHECK_EQ(2, FlagList::SetFlagsFromString(str, strlen(str)));
 }
 
@@ -141,7 +136,7 @@
 TEST(Flags5) {
   SetFlagsToDefault();
   int argc = 2;
-  const char* argv[] = { "Test5", "--int_flag=\"foobar\"" };
+  const char* argv[] = { "Test5", "--testing_int_flag=\"foobar\"" };
   CHECK_EQ(1, FlagList::SetFlagsFromCommandLine(&argc,
                                                 const_cast<char **>(argv),
                                                 true));
@@ -151,7 +146,7 @@
 
 TEST(Flags5b) {
   SetFlagsToDefault();
-  const char* str = "                     --int_flag=\"foobar\"";
+  const char* str = "                     --testing_int_flag=\"foobar\"";
   CHECK_EQ(1, FlagList::SetFlagsFromString(str, strlen(str)));
 }
 
@@ -159,7 +154,8 @@
 TEST(Flags6) {
   SetFlagsToDefault();
   int argc = 4;
-  const char* argv[] = { "Test5", "--int-flag", "0", "--float_flag" };
+  const char* argv[] = { "Test5", "--testing-int-flag", "0",
+                         "--testing_float_flag" };
   CHECK_EQ(3, FlagList::SetFlagsFromCommandLine(&argc,
                                                 const_cast<char **>(argv),
                                                 true));
@@ -169,6 +165,6 @@
 
 TEST(Flags6b) {
   SetFlagsToDefault();
-  const char* str = "              --int-flag 0       --float_flag    ";
+  const char* str = "       --testing-int-flag 0      --testing_float_flag    ";
   CHECK_EQ(3, FlagList::SetFlagsFromString(str, strlen(str)));
 }
diff --git a/test/cctest/test-mark-compact.cc b/test/cctest/test-mark-compact.cc
index 5d488df..36b286a 100644
--- a/test/cctest/test-mark-compact.cc
+++ b/test/cctest/test-mark-compact.cc
@@ -34,11 +34,6 @@
 #include "top.h"
 #include "cctest.h"
 
-namespace v8 { namespace internal {
-DECLARE_bool(gc_global);
-DECLARE_bool(always_compact);
-} }
-
 using namespace v8::internal;
 
 static v8::Persistent<v8::Context> env;
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index 3072664..7fc38a8 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -40,21 +40,8 @@
 #include "snapshot.h"
 #include "cctest.h"
 
-namespace v8 { namespace internal {
-
-#ifdef WIN32
-DEFINE_string(serialization_file, "C:\\Windows\\Temp\\serdes",
-              "file in which to serialize heap");
-#else
-DEFINE_string(serialization_file, "/tmp/serdes",
-              "file in which to serialize heap");
-#endif
-DECLARE_bool(debug_serialization);
-}}  // namespace v8::internal
-
 using namespace v8::internal;
 
-
 static int local_counters[256];
 static int counter_count = 0;
 static std::map<std::wstring, int> counter_table;
@@ -174,7 +161,7 @@
   v8::Persistent<v8::Context> env = v8::Context::New(&extensions);
   env->Enter();
 
-  Snapshot::WriteToFile(FLAG_serialization_file);
+  Snapshot::WriteToFile(FLAG_testing_serialization_file);
 }
 
 
@@ -218,7 +205,7 @@
 #ifdef DEBUG
   FLAG_debug_serialization = true;
 #endif
-  CHECK(Snapshot::Initialize(FLAG_serialization_file));
+  CHECK(Snapshot::Initialize(FLAG_testing_serialization_file));
 }
 
 
diff --git a/test/cctest/test-utils.cc b/test/cctest/test-utils.cc
index 8f06f0f..187cba9 100644
--- a/test/cctest/test-utils.cc
+++ b/test/cctest/test-utils.cc
@@ -162,17 +162,17 @@
   int length = strlen(s);
   for (int i = 1; i < length * 2; i++) {
     static const char kMarker = static_cast<char>(42);
-    char* buffer = NewArray<char>(i + 1);
+    Vector<char> buffer = Vector<char>::New(i + 1);
     buffer[i] = kMarker;
-    int n = OS::SNPrintF(buffer, i, "%s", s);
+    int n = OS::SNPrintF(Vector<char>(buffer.start(), i), "%s", s);
     CHECK(n <= i);
     CHECK(n == length || n == -1);
-    CHECK_EQ(0, strncmp(buffer, s, i - 1));
+    CHECK_EQ(0, strncmp(buffer.start(), s, i - 1));
     CHECK_EQ(kMarker, buffer[i]);
     if (i <= length) {
-      CHECK_EQ(i - 1, strlen(buffer));
+      CHECK_EQ(i - 1, strlen(buffer.start()));
     } else {
-      CHECK_EQ(length, strlen(buffer));
+      CHECK_EQ(length, strlen(buffer.start()));
     }
   }
 }
diff --git a/test/mjsunit/array-sort.js b/test/mjsunit/array-sort.js
index 398b721..49d5b38 100644
--- a/test/mjsunit/array-sort.js
+++ b/test/mjsunit/array-sort.js
@@ -25,6 +25,8 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --allow-natives-syntax
+
 // Test array sort.
 
 // Test counter-intuitive default number sorting.
@@ -49,10 +51,46 @@
   a.sort();
   assertArrayEquals([-123,-1234,-12345,-123456,0,0,123,1234,12345,123456], a);
 
+  // Tricky case avoiding integer overflow in Runtime_SmiLexicographicCompare.
+  a = [9, 1000000000].sort();
+  assertArrayEquals([1000000000, 9], a);
+  a = [1000000000, 1].sort();
+  assertArrayEquals([1, 1000000000], a);
+  a = [1000000000, 0].sort();
+  assertArrayEquals([0, 1000000000], a);
+
+  // One string is a prefix of the other.
+  a = [1230, 123].sort();
+  assertArrayEquals([123, 1230], a);
+  a = [1231, 123].sort();
+  assertArrayEquals([123, 1231], a);
+
   // Default sort on Smis and non-Smis.
   a = [1000000000, 10000000000, 1000000001, -1000000000, -10000000000, -1000000001];
   a.sort();
   assertArrayEquals([-1000000000, -10000000000, -1000000001, 1000000000, 10000000000, 1000000001], a);
+
+
+  for (var xb = 1; xb <= 1000 * 1000 * 1000; xb *= 10) {
+    for (var xf = 0; xf <= 9; xf++) {
+      for (var xo = -1; xo <= 1; xo++) {
+        for (var yb = 1; yb <= 1000 * 1000 * 1000; yb *= 10) {
+          for (var yf = 0; yf <= 9; yf++) {
+            for (var yo = -1; yo <= 1; yo++) {
+              var x = xb * xf + xo;
+              var y = yb * yf + yo;
+              if (!%_IsSmi(x)) continue;
+              if (!%_IsSmi(y)) continue;
+              var lex = %SmiLexicographicCompare(x, y);
+              if (lex < 0) lex = -1;
+              if (lex > 0) lex = 1;
+              assertEquals(lex, (x == y) ? 0 : ((x + "") < (y + "") ? -1 : 1), x + " < " + y);
+            }
+          }
+        }
+      }
+    }
+  }
 }
 
 TestNumberSort();
diff --git a/test/mjsunit/debug-script.js b/test/mjsunit/debug-script.js
index 55e83c1..4a77c3c 100644
--- a/test/mjsunit/debug-script.js
+++ b/test/mjsunit/debug-script.js
@@ -55,6 +55,9 @@
 
 // This has to be updated if the number of native scripts change.
 assertEquals(12, native_count);
+// If no snapshot is used, only the 'gc' extension is loaded.
+// If snapshot is used, all extensions are cached in the snapshot.
+assertTrue(extension_count == 1 || extension_count == 5);
 assertEquals(2, normal_count);  // This script and mjsunit.js.
 
 // Test a builtins script.
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index 4289bc4..76d2712 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -62,6 +62,3 @@
 debug-stepin-constructor: FAIL
 debug-step: FAIL
 regress/regress-998565: FAIL
-regress/regress-1081309: FAIL
-# Call as function does not always work on ARM port yet.
-number-string-index-call: FAIL
diff --git a/src/flags-inl.h b/test/mjsunit/regress/regress-69.js
similarity index 64%
rename from src/flags-inl.h
rename to test/mjsunit/regress/regress-69.js
index 2bbf581..3fb1f76 100644
--- a/src/flags-inl.h
+++ b/test/mjsunit/regress/regress-69.js
@@ -25,51 +25,19 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#ifndef V8_FLAGS_INL_H_
-#define V8_FLAGS_INL_H_
+// This tests a switch statement with only default clause leaves
+// balanced stack. It should not trigger the break point when --debug_code
+// flag is turned on.
+// See issue: http://code.google.com/p/v8/issues/detail?id=69
 
-namespace v8 { namespace internal {
-
-bool* Flag::bool_variable() const  {
-  ASSERT(type_ == BOOL);
-  return &variable_->b;
+// Flags: --debug-code --expose-gc
+function unbalanced_switch(a) {
+  try {
+    switch (a) {
+      default: break;
+    }
+  } catch (e) {}
+  gc();
 }
 
-int* Flag::int_variable() const {
-  ASSERT(type_ == INT);
-  return &variable_->i;
-}
-
-double* Flag::float_variable() const {
-  ASSERT(type_ == FLOAT);
-  return &variable_->f;
-}
-
-const char** Flag::string_variable() const {
-  ASSERT(type_ == STRING);
-  return &variable_->s;
-}
-
-bool Flag::bool_default() const {
-  ASSERT(type_ == BOOL);
-  return default_.b;
-}
-
-int Flag::int_default() const {
-  ASSERT(type_ == INT);
-  return default_.i;
-}
-
-double Flag::float_default() const {
-  ASSERT(type_ == FLOAT);
-  return default_.f;
-}
-
-const char* Flag::string_default() const {
-  ASSERT(type_ == STRING);
-  return default_.s;
-}
-
-} }  // namespace v8::internal
-
-#endif  // V8_FLAGS_INL_H_
+unbalanced_switch(1);
diff --git a/src/flags-inl.h b/test/mjsunit/with-function-expression.js
similarity index 64%
copy from src/flags-inl.h
copy to test/mjsunit/with-function-expression.js
index 2bbf581..17de817 100644
--- a/src/flags-inl.h
+++ b/test/mjsunit/with-function-expression.js
@@ -25,51 +25,12 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#ifndef V8_FLAGS_INL_H_
-#define V8_FLAGS_INL_H_
+var source = "(function x() { with({}) { return '' + x; } })()";
 
-namespace v8 { namespace internal {
+// Don't throw exceptions.
+assertDoesNotThrow(source);
 
-bool* Flag::bool_variable() const  {
-  ASSERT(type_ == BOOL);
-  return &variable_->b;
-}
-
-int* Flag::int_variable() const {
-  ASSERT(type_ == INT);
-  return &variable_->i;
-}
-
-double* Flag::float_variable() const {
-  ASSERT(type_ == FLOAT);
-  return &variable_->f;
-}
-
-const char** Flag::string_variable() const {
-  ASSERT(type_ == STRING);
-  return &variable_->s;
-}
-
-bool Flag::bool_default() const {
-  ASSERT(type_ == BOOL);
-  return default_.b;
-}
-
-int Flag::int_default() const {
-  ASSERT(type_ == INT);
-  return default_.i;
-}
-
-double Flag::float_default() const {
-  ASSERT(type_ == FLOAT);
-  return default_.f;
-}
-
-const char* Flag::string_default() const {
-  ASSERT(type_ == STRING);
-  return default_.s;
-}
-
-} }  // namespace v8::internal
-
-#endif  // V8_FLAGS_INL_H_
+// Check that the return value is a function.  Use regexp to avoid
+// depending on the exact printing of the function.
+var regexp = /function/;
+var res = assertTrue(eval(source).match(regexp) == 'function');
diff --git a/tools/presubmit.py b/tools/presubmit.py
index aa2c6b8..65812ec 100755
--- a/tools/presubmit.py
+++ b/tools/presubmit.py
@@ -134,6 +134,12 @@
     return (super(CppLintProcessor, self).IgnoreDir(name)
               or (name == 'third_party'))
 
+  IGNORE_LINT = ['flag-definitions.h']
+  
+  def IgnoreFile(self, name):
+    return (super(CppLintProcessor, self).IgnoreFile(name)
+              or (name in CppLintProcessor.IGNORE_LINT))
+
   def GetPathsToSearch(self):
     return ['src', 'public', 'samples', join('test', 'cctest')]
 
@@ -168,7 +174,8 @@
               or (name == 'third_party')
               or (name == 'obj'))
 
-  IGNORE_COPYRIGHTS = ['earley-boyer.js', 'raytrace.js', 'crypto.js']
+  IGNORE_COPYRIGHTS = ['earley-boyer.js', 'raytrace.js', 'crypto.js',
+      'libraries.cc', 'libraries-empty.cc']
   IGNORE_TABS = IGNORE_COPYRIGHTS + ['unicode-test.js',
       'html-comments.js']
 
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
index 6165204..632efd8 100644
--- a/tools/v8.xcodeproj/project.pbxproj
+++ b/tools/v8.xcodeproj/project.pbxproj
@@ -16,6 +16,8 @@
 				7BF8919B0E7309AD000BAF8A /* PBXTargetDependency */,
 				7BF891970E73099F000BAF8A /* PBXTargetDependency */,
 				7BF891990E73099F000BAF8A /* PBXTargetDependency */,
+				896FD03E0E78D731003DFB6A /* PBXTargetDependency */,
+				896FD0400E78D735003DFB6A /* PBXTargetDependency */,
 			);
 			name = All;
 			productName = All;
@@ -25,6 +27,9 @@
 /* Begin PBXBuildFile section */
 		8900116C0E71CA2300F91F35 /* libraries.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8900116B0E71CA2300F91F35 /* libraries.cc */; };
 		893CCE640E71D83700357A03 /* code-stubs.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1110E719B8F00D62E90 /* code-stubs.cc */; };
+		89495E480E79FC23001F68C3 /* compilation-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89495E460E79FC23001F68C3 /* compilation-cache.cc */; };
+		89495E490E79FC23001F68C3 /* compilation-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89495E460E79FC23001F68C3 /* compilation-cache.cc */; };
+		896FD03A0E78D717003DFB6A /* libv8-arm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 89F23C870E78D5B2006B2466 /* libv8-arm.a */; };
 		897F767F0E71B690007ACF34 /* shell.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1B50E719C0900D62E90 /* shell.cc */; };
 		897F76840E71B6B1007ACF34 /* libjscre.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 897FF1BF0E719CB600D62E90 /* libjscre.a */; };
 		897F76850E71B6B1007ACF34 /* libv8.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8970F2F00E719FB2006AE7B5 /* libv8.a */; };
@@ -99,6 +104,77 @@
 		89A88E2C0E71A6D20043BA31 /* v8threads.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19D0E719B8F00D62E90 /* v8threads.cc */; };
 		89A88E2D0E71A6D50043BA31 /* variables.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19F0E719B8F00D62E90 /* variables.cc */; };
 		89A88E2E0E71A6D60043BA31 /* zone.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1A20E719B8F00D62E90 /* zone.cc */; };
+		89F23C3F0E78D5B2006B2466 /* accessors.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0F60E719B8F00D62E90 /* accessors.cc */; };
+		89F23C400E78D5B2006B2466 /* allocation.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0F80E719B8F00D62E90 /* allocation.cc */; };
+		89F23C410E78D5B2006B2466 /* api.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0FA0E719B8F00D62E90 /* api.cc */; };
+		89F23C430E78D5B2006B2466 /* assembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1030E719B8F00D62E90 /* assembler.cc */; };
+		89F23C440E78D5B2006B2466 /* ast.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1050E719B8F00D62E90 /* ast.cc */; };
+		89F23C450E78D5B2006B2466 /* bootstrapper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1070E719B8F00D62E90 /* bootstrapper.cc */; };
+		89F23C470E78D5B2006B2466 /* builtins.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF10B0E719B8F00D62E90 /* builtins.cc */; };
+		89F23C480E78D5B2006B2466 /* checks.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF10F0E719B8F00D62E90 /* checks.cc */; };
+		89F23C490E78D5B2006B2466 /* code-stubs.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1110E719B8F00D62E90 /* code-stubs.cc */; };
+		89F23C4B0E78D5B2006B2466 /* codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1170E719B8F00D62E90 /* codegen.cc */; };
+		89F23C4C0E78D5B2006B2466 /* compiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1190E719B8F00D62E90 /* compiler.cc */; };
+		89F23C4D0E78D5B2006B2466 /* contexts.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF11C0E719B8F00D62E90 /* contexts.cc */; };
+		89F23C4E0E78D5B2006B2466 /* conversions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF11F0E719B8F00D62E90 /* conversions.cc */; };
+		89F23C4F0E78D5B2006B2466 /* counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1210E719B8F00D62E90 /* counters.cc */; };
+		89F23C510E78D5B2006B2466 /* dateparser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1260E719B8F00D62E90 /* dateparser.cc */; };
+		89F23C520E78D5B2006B2466 /* debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1280E719B8F00D62E90 /* debug.cc */; };
+		89F23C540E78D5B2006B2466 /* disassembler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF12D0E719B8F00D62E90 /* disassembler.cc */; };
+		89F23C550E78D5B2006B2466 /* dtoa-config.c in Sources */ = {isa = PBXBuildFile; fileRef = 897FF12F0E719B8F00D62E90 /* dtoa-config.c */; };
+		89F23C560E78D5B2006B2466 /* execution.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1300E719B8F00D62E90 /* execution.cc */; };
+		89F23C570E78D5B2006B2466 /* factory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1320E719B8F00D62E90 /* factory.cc */; };
+		89F23C580E78D5B2006B2466 /* flags.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1350E719B8F00D62E90 /* flags.cc */; };
+		89F23C5A0E78D5B2006B2466 /* frames.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF13C0E719B8F00D62E90 /* frames.cc */; };
+		89F23C5B0E78D5B2006B2466 /* global-handles.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF13E0E719B8F00D62E90 /* global-handles.cc */; };
+		89F23C5C0E78D5B2006B2466 /* handles.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1420E719B8F00D62E90 /* handles.cc */; };
+		89F23C5D0E78D5B2006B2466 /* hashmap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1440E719B8F00D62E90 /* hashmap.cc */; };
+		89F23C5E0E78D5B2006B2466 /* heap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1470E719B8F00D62E90 /* heap.cc */; };
+		89F23C600E78D5B2006B2466 /* ic.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF14C0E719B8F00D62E90 /* ic.cc */; };
+		89F23C610E78D5B2006B2466 /* jsregexp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF14E0E719B8F00D62E90 /* jsregexp.cc */; };
+		89F23C620E78D5B2006B2466 /* libraries.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8900116B0E71CA2300F91F35 /* libraries.cc */; };
+		89F23C630E78D5B2006B2466 /* log.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1520E719B8F00D62E90 /* log.cc */; };
+		89F23C650E78D5B2006B2466 /* mark-compact.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1590E719B8F00D62E90 /* mark-compact.cc */; };
+		89F23C660E78D5B2006B2466 /* messages.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF15C0E719B8F00D62E90 /* messages.cc */; };
+		89F23C670E78D5B2006B2466 /* objects-debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1600E719B8F00D62E90 /* objects-debug.cc */; };
+		89F23C680E78D5B2006B2466 /* objects.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1620E719B8F00D62E90 /* objects.cc */; };
+		89F23C690E78D5B2006B2466 /* parser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1640E719B8F00D62E90 /* parser.cc */; };
+		89F23C6A0E78D5B2006B2466 /* platform-macos.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1670E719B8F00D62E90 /* platform-macos.cc */; };
+		89F23C6B0E78D5B2006B2466 /* prettyprinter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16B0E719B8F00D62E90 /* prettyprinter.cc */; };
+		89F23C6C0E78D5B2006B2466 /* property.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16D0E719B8F00D62E90 /* property.cc */; };
+		89F23C6D0E78D5B2006B2466 /* rewriter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16F0E719B8F00D62E90 /* rewriter.cc */; };
+		89F23C6E0E78D5B2006B2466 /* runtime.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1710E719B8F00D62E90 /* runtime.cc */; };
+		89F23C6F0E78D5B2006B2466 /* scanner.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1730E719B8F00D62E90 /* scanner.cc */; };
+		89F23C700E78D5B2006B2466 /* scopeinfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1760E719B8F00D62E90 /* scopeinfo.cc */; };
+		89F23C710E78D5B2006B2466 /* scopes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1780E719B8F00D62E90 /* scopes.cc */; };
+		89F23C720E78D5B2006B2466 /* serialize.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF17A0E719B8F00D62E90 /* serialize.cc */; };
+		89F23C730E78D5B2006B2466 /* snapshot-common.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1820E719B8F00D62E90 /* snapshot-common.cc */; };
+		89F23C740E78D5B2006B2466 /* snapshot-empty.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1830E719B8F00D62E90 /* snapshot-empty.cc */; };
+		89F23C750E78D5B2006B2466 /* spaces.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1860E719B8F00D62E90 /* spaces.cc */; };
+		89F23C760E78D5B2006B2466 /* string-stream.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-stream.cc */; };
+		89F23C780E78D5B2006B2466 /* stub-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18C0E719B8F00D62E90 /* stub-cache.cc */; };
+		89F23C790E78D5B2006B2466 /* token.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18E0E719B8F00D62E90 /* token.cc */; };
+		89F23C7A0E78D5B2006B2466 /* top.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1900E719B8F00D62E90 /* top.cc */; };
+		89F23C7B0E78D5B2006B2466 /* unicode.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1930E719B8F00D62E90 /* unicode.cc */; };
+		89F23C7C0E78D5B2006B2466 /* usage-analyzer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1950E719B8F00D62E90 /* usage-analyzer.cc */; };
+		89F23C7D0E78D5B2006B2466 /* utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1970E719B8F00D62E90 /* utils.cc */; };
+		89F23C7E0E78D5B2006B2466 /* v8-counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1990E719B8F00D62E90 /* v8-counters.cc */; };
+		89F23C7F0E78D5B2006B2466 /* v8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19B0E719B8F00D62E90 /* v8.cc */; };
+		89F23C800E78D5B2006B2466 /* v8threads.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19D0E719B8F00D62E90 /* v8threads.cc */; };
+		89F23C810E78D5B2006B2466 /* variables.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19F0E719B8F00D62E90 /* variables.cc */; };
+		89F23C820E78D5B2006B2466 /* zone.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1A20E719B8F00D62E90 /* zone.cc */; };
+		89F23C8E0E78D5B6006B2466 /* shell.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1B50E719C0900D62E90 /* shell.cc */; };
+		89F23C900E78D5B6006B2466 /* libjscre.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 897FF1BF0E719CB600D62E90 /* libjscre.a */; };
+		89F23C970E78D5E3006B2466 /* assembler-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF0FE0E719B8F00D62E90 /* assembler-arm.cc */; };
+		89F23C980E78D5E7006B2466 /* builtins-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1090E719B8F00D62E90 /* builtins-arm.cc */; };
+		89F23C990E78D5E9006B2466 /* codegen-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1140E719B8F00D62E90 /* codegen-arm.cc */; };
+		89F23C9A0E78D5EC006B2466 /* cpu-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1230E719B8F00D62E90 /* cpu-arm.cc */; };
+		89F23C9B0E78D5EE006B2466 /* disasm-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF12A0E719B8F00D62E90 /* disasm-arm.cc */; };
+		89F23C9C0E78D5F1006B2466 /* frames-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1370E719B8F00D62E90 /* frames-arm.cc */; };
+		89F23C9D0E78D5FB006B2466 /* ic-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1490E719B8F00D62E90 /* ic-arm.cc */; };
+		89F23C9E0E78D5FD006B2466 /* macro-assembler-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1540E719B8F00D62E90 /* macro-assembler-arm.cc */; };
+		89F23C9F0E78D604006B2466 /* simulator-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF17D0E719B8F00D62E90 /* simulator-arm.cc */; };
+		89F23CA00E78D609006B2466 /* stub-cache-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -123,6 +199,27 @@
 			remoteGlobalIDString = 897FF1BE0E719CB600D62E90;
 			remoteInfo = jscre;
 		};
+		896FD03B0E78D71F003DFB6A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 89F23C3C0E78D5B2006B2466;
+			remoteInfo = "v8-arm";
+		};
+		896FD03D0E78D731003DFB6A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 89F23C3C0E78D5B2006B2466;
+			remoteInfo = "v8-arm";
+		};
+		896FD03F0E78D735003DFB6A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 89F23C880E78D5B6006B2466;
+			remoteInfo = "v8_shell-arm";
+		};
 		897F76800E71B6AC007ACF34 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
@@ -137,10 +234,19 @@
 			remoteGlobalIDString = 8970F2EF0E719FB2006AE7B5;
 			remoteInfo = v8;
 		};
+		89F23C8A0E78D5B6006B2466 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 8915B8680E719336009C4E19 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 897FF1BE0E719CB600D62E90;
+			remoteInfo = jscre;
+		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
 		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>"; };
 		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>"; };
@@ -224,7 +330,6 @@
 		897FF1310E719B8F00D62E90 /* execution.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = execution.h; sourceTree = "<group>"; };
 		897FF1320E719B8F00D62E90 /* factory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = factory.cc; sourceTree = "<group>"; };
 		897FF1330E719B8F00D62E90 /* factory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = factory.h; sourceTree = "<group>"; };
-		897FF1340E719B8F00D62E90 /* flags-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "flags-inl.h"; sourceTree = "<group>"; };
 		897FF1350E719B8F00D62E90 /* flags.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = flags.cc; sourceTree = "<group>"; };
 		897FF1360E719B8F00D62E90 /* flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = flags.h; sourceTree = "<group>"; };
 		897FF1370E719B8F00D62E90 /* frames-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "frames-arm.cc"; sourceTree = "<group>"; };
@@ -351,7 +456,10 @@
 		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; };
+		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 */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -378,6 +486,22 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		89F23C830E78D5B2006B2466 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		89F23C8F0E78D5B6006B2466 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				89F23C900E78D5B6006B2466 /* libjscre.a in Frameworks */,
+				896FD03A0E78D717003DFB6A /* libv8-arm.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
@@ -459,6 +583,8 @@
 				897FF1160E719B8F00D62E90 /* codegen-inl.h */,
 				897FF1170E719B8F00D62E90 /* codegen.cc */,
 				897FF1180E719B8F00D62E90 /* codegen.h */,
+				89495E460E79FC23001F68C3 /* compilation-cache.cc */,
+				89495E470E79FC23001F68C3 /* compilation-cache.h */,
 				897FF1190E719B8F00D62E90 /* compiler.cc */,
 				897FF11A0E719B8F00D62E90 /* compiler.h */,
 				897FF11B0E719B8F00D62E90 /* constants-arm.h */,
@@ -486,7 +612,6 @@
 				897FF1310E719B8F00D62E90 /* execution.h */,
 				897FF1320E719B8F00D62E90 /* factory.cc */,
 				897FF1330E719B8F00D62E90 /* factory.h */,
-				897FF1340E719B8F00D62E90 /* flags-inl.h */,
 				897FF1350E719B8F00D62E90 /* flags.cc */,
 				897FF1360E719B8F00D62E90 /* flags.h */,
 				897FF1370E719B8F00D62E90 /* frames-arm.cc */,
@@ -674,6 +799,7 @@
 			children = (
 				897FF1B60E719C2300D62E90 /* js2c.py */,
 				897FF1B70E719C2E00D62E90 /* macros.py */,
+				89B12E8D0E7FF2A40080BA62 /* presubmit.py */,
 			);
 			path = tools;
 			sourceTree = "<group>";
@@ -684,6 +810,8 @@
 				897FF1BF0E719CB600D62E90 /* libjscre.a */,
 				8970F2F00E719FB2006AE7B5 /* libv8.a */,
 				897F767A0E71B4CC007ACF34 /* v8_shell */,
+				89F23C870E78D5B2006B2466 /* libv8-arm.a */,
+				89F23C950E78D5B6006B2466 /* v8_shell-arm */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -750,6 +878,41 @@
 			productReference = 897FF1BF0E719CB600D62E90 /* libjscre.a */;
 			productType = "com.apple.product-type.library.static";
 		};
+		89F23C3C0E78D5B2006B2466 /* v8-arm */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 89F23C840E78D5B2006B2466 /* Build configuration list for PBXNativeTarget "v8-arm" */;
+			buildPhases = (
+				89F23C3D0E78D5B2006B2466 /* ShellScript */,
+				89F23C3E0E78D5B2006B2466 /* Sources */,
+				89F23C830E78D5B2006B2466 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "v8-arm";
+			productName = "v8-arm";
+			productReference = 89F23C870E78D5B2006B2466 /* libv8-arm.a */;
+			productType = "com.apple.product-type.library.static";
+		};
+		89F23C880E78D5B6006B2466 /* v8_shell-arm */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 89F23C920E78D5B6006B2466 /* Build configuration list for PBXNativeTarget "v8_shell-arm" */;
+			buildPhases = (
+				89F23C8D0E78D5B6006B2466 /* Sources */,
+				89F23C8F0E78D5B6006B2466 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				89F23C890E78D5B6006B2466 /* PBXTargetDependency */,
+				896FD03C0E78D71F003DFB6A /* PBXTargetDependency */,
+			);
+			name = "v8_shell-arm";
+			productName = "v8_shell-arm";
+			productReference = 89F23C950E78D5B6006B2466 /* v8_shell-arm */;
+			productType = "com.apple.product-type.tool";
+		};
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
@@ -767,6 +930,8 @@
 				897FF1BE0E719CB600D62E90 /* jscre */,
 				8970F2EF0E719FB2006AE7B5 /* v8 */,
 				897F76790E71B4CC007ACF34 /* v8_shell */,
+				89F23C3C0E78D5B2006B2466 /* v8-arm */,
+				89F23C880E78D5B6006B2466 /* v8_shell-arm */,
 			);
 		};
 /* End PBXProject section */
@@ -785,6 +950,19 @@
 			shellPath = /bin/sh;
 			shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-delay.js\"\\\n\" mirror-delay.js\"\\\n\" date-delay.js\"\\\n\" regexp-delay.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nLIBRARIES_EMPTY_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries-empty.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${LIBRARIES_CC}.new\" \\\n  \"${LIBRARIES_EMPTY_CC}.new\" \\\n  ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n  rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\"\nelse\n  rm \"${LIBRARIES_EMPTY_CC}.new\"\nfi\n";
 		};
+		89F23C3D0E78D5B2006B2466 /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-delay.js\"\\\n\" mirror-delay.js\"\\\n\" date-delay.js\"\\\n\" regexp-delay.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nLIBRARIES_EMPTY_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries-empty.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${LIBRARIES_CC}.new\" \\\n  \"${LIBRARIES_EMPTY_CC}.new\" \\\n  ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n  rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\"\nelse\n  rm \"${LIBRARIES_EMPTY_CC}.new\"\nfi\n";
+		};
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
@@ -805,6 +983,7 @@
 				893CCE640E71D83700357A03 /* code-stubs.cc in Sources */,
 				89A88DF70E71A6240043BA31 /* codegen-ia32.cc in Sources */,
 				89A88DF80E71A6260043BA31 /* codegen.cc in Sources */,
+				89495E480E79FC23001F68C3 /* compilation-cache.cc in Sources */,
 				89A88DF90E71A6430043BA31 /* compiler.cc in Sources */,
 				89A88DFA0E71A6440043BA31 /* contexts.cc in Sources */,
 				89A88DFB0E71A6440043BA31 /* conversions.cc in Sources */,
@@ -883,6 +1062,91 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		89F23C3E0E78D5B2006B2466 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				89F23C3F0E78D5B2006B2466 /* accessors.cc in Sources */,
+				89F23C400E78D5B2006B2466 /* allocation.cc in Sources */,
+				89F23C410E78D5B2006B2466 /* api.cc in Sources */,
+				89F23C970E78D5E3006B2466 /* assembler-arm.cc in Sources */,
+				89F23C430E78D5B2006B2466 /* assembler.cc in Sources */,
+				89F23C440E78D5B2006B2466 /* ast.cc in Sources */,
+				89F23C450E78D5B2006B2466 /* bootstrapper.cc in Sources */,
+				89F23C980E78D5E7006B2466 /* builtins-arm.cc in Sources */,
+				89F23C470E78D5B2006B2466 /* builtins.cc in Sources */,
+				89F23C480E78D5B2006B2466 /* checks.cc in Sources */,
+				89F23C490E78D5B2006B2466 /* code-stubs.cc in Sources */,
+				89F23C990E78D5E9006B2466 /* codegen-arm.cc in Sources */,
+				89F23C4B0E78D5B2006B2466 /* codegen.cc in Sources */,
+				89495E490E79FC23001F68C3 /* compilation-cache.cc in Sources */,
+				89F23C4C0E78D5B2006B2466 /* compiler.cc in Sources */,
+				89F23C4D0E78D5B2006B2466 /* contexts.cc in Sources */,
+				89F23C4E0E78D5B2006B2466 /* conversions.cc in Sources */,
+				89F23C4F0E78D5B2006B2466 /* counters.cc in Sources */,
+				89F23C9A0E78D5EC006B2466 /* cpu-arm.cc in Sources */,
+				89F23C510E78D5B2006B2466 /* dateparser.cc in Sources */,
+				89F23C520E78D5B2006B2466 /* debug.cc in Sources */,
+				89F23C9B0E78D5EE006B2466 /* disasm-arm.cc in Sources */,
+				89F23C540E78D5B2006B2466 /* disassembler.cc in Sources */,
+				89F23C550E78D5B2006B2466 /* dtoa-config.c in Sources */,
+				89F23C560E78D5B2006B2466 /* execution.cc in Sources */,
+				89F23C570E78D5B2006B2466 /* factory.cc in Sources */,
+				89F23C580E78D5B2006B2466 /* flags.cc in Sources */,
+				89F23C9C0E78D5F1006B2466 /* frames-arm.cc in Sources */,
+				89F23C5A0E78D5B2006B2466 /* frames.cc in Sources */,
+				89F23C5B0E78D5B2006B2466 /* global-handles.cc in Sources */,
+				89F23C5C0E78D5B2006B2466 /* handles.cc in Sources */,
+				89F23C5D0E78D5B2006B2466 /* hashmap.cc in Sources */,
+				89F23C5E0E78D5B2006B2466 /* heap.cc in Sources */,
+				89F23C9D0E78D5FB006B2466 /* ic-arm.cc in Sources */,
+				89F23C600E78D5B2006B2466 /* ic.cc in Sources */,
+				89F23C610E78D5B2006B2466 /* jsregexp.cc in Sources */,
+				89F23C620E78D5B2006B2466 /* libraries.cc in Sources */,
+				89F23C630E78D5B2006B2466 /* log.cc in Sources */,
+				89F23C9E0E78D5FD006B2466 /* macro-assembler-arm.cc in Sources */,
+				89F23C650E78D5B2006B2466 /* mark-compact.cc in Sources */,
+				89F23C660E78D5B2006B2466 /* messages.cc in Sources */,
+				89F23C670E78D5B2006B2466 /* objects-debug.cc in Sources */,
+				89F23C680E78D5B2006B2466 /* objects.cc in Sources */,
+				89F23C690E78D5B2006B2466 /* parser.cc in Sources */,
+				89F23C6A0E78D5B2006B2466 /* platform-macos.cc in Sources */,
+				89F23C6B0E78D5B2006B2466 /* prettyprinter.cc in Sources */,
+				89F23C6C0E78D5B2006B2466 /* property.cc in Sources */,
+				89F23C6D0E78D5B2006B2466 /* rewriter.cc in Sources */,
+				89F23C6E0E78D5B2006B2466 /* runtime.cc in Sources */,
+				89F23C6F0E78D5B2006B2466 /* scanner.cc in Sources */,
+				89F23C700E78D5B2006B2466 /* scopeinfo.cc in Sources */,
+				89F23C710E78D5B2006B2466 /* scopes.cc in Sources */,
+				89F23C720E78D5B2006B2466 /* serialize.cc in Sources */,
+				89F23C9F0E78D604006B2466 /* simulator-arm.cc in Sources */,
+				89F23C730E78D5B2006B2466 /* snapshot-common.cc in Sources */,
+				89F23C740E78D5B2006B2466 /* snapshot-empty.cc in Sources */,
+				89F23C750E78D5B2006B2466 /* spaces.cc in Sources */,
+				89F23C760E78D5B2006B2466 /* string-stream.cc in Sources */,
+				89F23CA00E78D609006B2466 /* stub-cache-arm.cc in Sources */,
+				89F23C780E78D5B2006B2466 /* stub-cache.cc in Sources */,
+				89F23C790E78D5B2006B2466 /* token.cc in Sources */,
+				89F23C7A0E78D5B2006B2466 /* top.cc in Sources */,
+				89F23C7B0E78D5B2006B2466 /* unicode.cc in Sources */,
+				89F23C7C0E78D5B2006B2466 /* usage-analyzer.cc in Sources */,
+				89F23C7D0E78D5B2006B2466 /* utils.cc in Sources */,
+				89F23C7E0E78D5B2006B2466 /* v8-counters.cc in Sources */,
+				89F23C7F0E78D5B2006B2466 /* v8.cc in Sources */,
+				89F23C800E78D5B2006B2466 /* v8threads.cc in Sources */,
+				89F23C810E78D5B2006B2466 /* variables.cc in Sources */,
+				89F23C820E78D5B2006B2466 /* zone.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		89F23C8D0E78D5B6006B2466 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				89F23C8E0E78D5B6006B2466 /* shell.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
@@ -901,6 +1165,21 @@
 			target = 897FF1BE0E719CB600D62E90 /* jscre */;
 			targetProxy = 7BF8919A0E7309AD000BAF8A /* PBXContainerItemProxy */;
 		};
+		896FD03C0E78D71F003DFB6A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 89F23C3C0E78D5B2006B2466 /* v8-arm */;
+			targetProxy = 896FD03B0E78D71F003DFB6A /* PBXContainerItemProxy */;
+		};
+		896FD03E0E78D731003DFB6A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 89F23C3C0E78D5B2006B2466 /* v8-arm */;
+			targetProxy = 896FD03D0E78D731003DFB6A /* PBXContainerItemProxy */;
+		};
+		896FD0400E78D735003DFB6A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 89F23C880E78D5B6006B2466 /* v8_shell-arm */;
+			targetProxy = 896FD03F0E78D735003DFB6A /* PBXContainerItemProxy */;
+		};
 		897F76810E71B6AC007ACF34 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 897FF1BE0E719CB600D62E90 /* jscre */;
@@ -911,6 +1190,11 @@
 			target = 8970F2EF0E719FB2006AE7B5 /* v8 */;
 			targetProxy = 897F76820E71B6AC007ACF34 /* PBXContainerItemProxy */;
 		};
+		89F23C890E78D5B6006B2466 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 897FF1BE0E719CB600D62E90 /* jscre */;
+			targetProxy = 89F23C8A0E78D5B6006B2466 /* PBXContainerItemProxy */;
+		};
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
@@ -1074,6 +1358,52 @@
 			};
 			name = Release;
 		};
+		89F23C850E78D5B2006B2466 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DEPLOYMENT_POSTPROCESSING = NO;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+					ARM,
+					ENABLE_DISASSEMBLER,
+					ENABLE_LOGGING_AND_PROFILING,
+				);
+				HEADER_SEARCH_PATHS = ../src;
+				PRODUCT_NAME = "v8-arm";
+				STRIP_STYLE = debugging;
+			};
+			name = Debug;
+		};
+		89F23C860E78D5B2006B2466 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DEPLOYMENT_POSTPROCESSING = NO;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+					ARM,
+				);
+				HEADER_SEARCH_PATHS = ../src;
+				PRODUCT_NAME = "v8-arm";
+				STRIP_STYLE = debugging;
+			};
+			name = Release;
+		};
+		89F23C930E78D5B6006B2466 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				HEADER_SEARCH_PATHS = ../src;
+				PRODUCT_NAME = "v8_shell-arm";
+			};
+			name = Debug;
+		};
+		89F23C940E78D5B6006B2466 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				HEADER_SEARCH_PATHS = ../src;
+				PRODUCT_NAME = "v8_shell-arm";
+			};
+			name = Release;
+		};
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
@@ -1122,6 +1452,24 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
+		89F23C840E78D5B2006B2466 /* Build configuration list for PBXNativeTarget "v8-arm" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				89F23C850E78D5B2006B2466 /* Debug */,
+				89F23C860E78D5B2006B2466 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		89F23C920E78D5B6006B2466 /* Build configuration list for PBXNativeTarget "v8_shell-arm" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				89F23C930E78D5B6006B2466 /* Debug */,
+				89F23C940E78D5B6006B2466 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 /* End XCConfigurationList section */
 	};
 	rootObject = 8915B8680E719336009C4E19 /* Project object */;
diff --git a/tools/visual_studio/v8_base.vcproj b/tools/visual_studio/v8_base.vcproj
index b8856e1..80576f1 100644
--- a/tools/visual_studio/v8_base.vcproj
+++ b/tools/visual_studio/v8_base.vcproj
@@ -381,6 +381,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\compilation-cache.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\compilation-cache.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\compiler.cc"
 				>
 			</File>