Improved performance of garbage collection by changing the way we use the marking...
authormads.s.ager <mads.s.ager@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 13 Aug 2008 09:32:07 +0000 (09:32 +0000)
committermads.s.ager <mads.s.ager@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 13 Aug 2008 09:32:07 +0000 (09:32 +0000)
Cleaned up ARM version by removing top of stack caching and by introducing push/pop elimination.

Cleaned up the way runtime functions are called to allow runtime calls with no arguments.

Changed Windows build options to make sure that exceptions are disabled and that optimization flags are enabled.

Added first version of Visual Studio project files.

git-svn-id: http://v8.googlecode.com/svn/trunk@13 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

62 files changed:
ChangeLog
src/SConscript
src/api.cc
src/arguments.h
src/assembler-arm-inl.h
src/assembler-arm.cc
src/assembler-arm.h
src/assembler.cc
src/assembler.h
src/builtins-arm.cc
src/builtins-ia32.cc
src/builtins.cc
src/code-stubs.h
src/code.h
src/codegen-arm.cc
src/codegen-ia32.cc
src/codegen.cc
src/codegen.h
src/date-delay.js
src/debug-delay.js
src/debug.cc
src/disassembler.cc
src/factory.cc
src/frames-arm.h
src/frames.h
src/heap.h
src/ic-arm.cc
src/ic-ia32.cc
src/ic.h
src/macro-assembler-arm.cc
src/macro-assembler-arm.h
src/macro-assembler-ia32.cc
src/macro-assembler-ia32.h
src/mark-compact.cc
src/mark-compact.h
src/math.js
src/messages.js
src/objects-debug.cc
src/objects.cc
src/objects.h
src/platform.h
src/regexp-delay.js
src/runtime.cc
src/runtime.h
src/runtime.js
src/serialize.cc
src/string.js
src/stub-cache-arm.cc
src/stub-cache-ia32.cc
src/utils.h
src/v8.h
src/v8natives.js
tools/js2c.py
tools/visual_studio/README.txt [new file with mode: 0644]
tools/visual_studio/common.vsprops [new file with mode: 0644]
tools/visual_studio/debug.vsprops [new file with mode: 0644]
tools/visual_studio/js2c.cmd [new file with mode: 0644]
tools/visual_studio/release.vsprops [new file with mode: 0644]
tools/visual_studio/v8.vcproj [new file with mode: 0644]
tools/visual_studio/v8_base.vcproj [new file with mode: 0644]
tools/visual_studio/v8_mksnapshot.vcproj [new file with mode: 0644]
tools/visual_studio/v8_snapshot.vcproj [new file with mode: 0644]

index 021ea6114758ea85007ead515231af3d09b74469..14a3857ea48714d764a9577afc0f0d217b79c3e8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2008-08-13: Version 0.2.2 (130807)
+
+        Improved performance of garbage collection by changing the way
+        we use the marking stack in the event of stack overflow during
+        full garbage collection and by changing the way we mark roots.
+
+        Cleaned up ARM version by removing top of stack caching and by
+        introducing push/pop elimination.
+
+        Cleaned up the way runtime functions are called to allow
+        runtime calls with no arguments.
+
+        Changed Windows build options to make sure that exceptions are
+        disabled and that optimization flags are enabled.
+
+        Added first version of Visual Studio project files.
+
+
 2008-08-06: Version 0.2.1 (130029)
 
         Improved performance of unary addition by avoiding runtime calls.
@@ -19,7 +37,7 @@
         Added platform-nullos.cc to serve as the basis for new platform
         implementations.
 
-        
+
 2008-07-30: Version 0.2.0 (129146)
 
         Changed all text files to have native svn:eol-style.
index d784fa4caad29db9ac8ef0768c033e9f14558817..407ab5f0209b24ea8f5e6e4a27ea27084a3da274 100644 (file)
@@ -94,11 +94,10 @@ BUILD_OPTIONS_MAP = {
         'ARFLAGS': '/NOLOGO',
         'CCFLAGS': '$DIALECTFLAGS $WARNINGFLAGS /Od /Gm /MTd',
         'CCPDBFLAGS': '/Zi',
-        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING', 'DEBUG', '_DEBUG', 'ENABLE_DISASSEMBLER'],
-        'CXXFLAGS': '$CCFLAGS /EHsc /GS- /GR-',
+        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', '_HAS_EXCEPTIONS=0', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING', 'DEBUG', '_DEBUG', 'ENABLE_DISASSEMBLER'],
+        'CXXFLAGS': '$CCFLAGS /GS- /GR- /Gy',
         'DIALECTFLAGS': '/nologo',
-        'LIBS': 'WS2_32',
-        'LINKFLAGS': '/NOLOGO /SUBSYSTEM:CONSOLE /MACHINE:X86 /INCREMENTAL:NO /DEBUG',
+        'LINKFLAGS': '/NOLOGO /MACHINE:X86 /INCREMENTAL:NO /NXCOMPAT /IGNORE:4221 /DEBUG',
         'PDB': '${TARGET}.pdb',
         'WARNINGFLAGS': '/W3 /WX /wd4355 /wd4800'
       },
@@ -106,11 +105,10 @@ BUILD_OPTIONS_MAP = {
         'ARFLAGS': '/NOLOGO',
         'CCFLAGS': '$DIALECTFLAGS $WARNINGFLAGS /Od /Gm /MTd',
         'CCPDBFLAGS': '/Zi',
-        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING', 'DEBUG', '_DEBUG', 'ENABLE_DISASSEMBLER'],
-        'CXXFLAGS': '$CCFLAGS /EHsc /GS- /GR-',
+        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', '_HAS_EXCEPTIONS=0', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING', 'DEBUG', '_DEBUG', 'ENABLE_DISASSEMBLER'],
+        'CXXFLAGS': '$CCFLAGS /GS- /GR- /Gy',
         'DIALECTFLAGS': '/nologo',
-        'LIBS': 'WS2_32',
-        'LINKFLAGS': '/NOLOGO /SUBSYSTEM:CONSOLE /MACHINE:X86 /INCREMENTAL:NO /DEBUG',
+        'LINKFLAGS': '/NOLOGO /MACHINE:X86 /INCREMENTAL:NO /NXCOMPAT /IGNORE:4221 /DEBUG',
         'PDB': '${TARGET}.pdb',
         'WARNINGFLAGS': '/WX /wd4018 /wd4244'
       },
@@ -118,51 +116,47 @@ BUILD_OPTIONS_MAP = {
         'ARFLAGS': '/NOLOGO',
         'CCFLAGS': '$DIALECTFLAGS $WARNINGFLAGS /Od /Gm /MTd',
         'CCPDBFLAGS': '/Zi',
-        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING', 'DEBUG', '_DEBUG', 'ENABLE_DISASSEMBLER', 'SUPPORT_UTF8', 'NO_RECURSE', 'SUPPORT_UCP'],
-        'CXXFLAGS': '$CCFLAGS /EHsc /GS- /GR-',
+        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', '_HAS_EXCEPTIONS=0', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING', 'DEBUG', '_DEBUG', 'ENABLE_DISASSEMBLER', 'SUPPORT_UTF8', 'NO_RECURSE', 'SUPPORT_UCP'],
+        'CXXFLAGS': '$CCFLAGS /GS- /GR- /Gy',
         'DIALECTFLAGS': '/nologo',
-        'LIBS': 'WS2_32',
-        'LINKFLAGS': '/NOLOGO /SUBSYSTEM:CONSOLE /MACHINE:X86 /INCREMENTAL:NO /DEBUG',
+        'LINKFLAGS': '/NOLOGO /MACHINE:X86 /INCREMENTAL:NO /NXCOMPAT /IGNORE:4221 /DEBUG',
         'PDB': '${TARGET}.pdb',
-        'WARNINGFLAGS': '/WX /wd4003 /wd4005 /wd4018 /wd4133'
+        'WARNINGFLAGS': '/W3 /WX /wd4355 /wd4800'
       }
     },
     'release': {
       'default': {
         'ARFLAGS': '/NOLOGO',
-        'CCFLAGS': '$DIALECTFLAGS $WARNINGFLAGS /O2 /MT',
+        'CCFLAGS': '$DIALECTFLAGS $WARNINGFLAGS /Ox /MT /Ob2 /Oi /Oy',
         'CCPDBFLAGS': '/Zi',
-        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING'],
-        'CXXFLAGS': '$CCFLAGS /EHsc /GS- /GR-',
+        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', '_HAS_EXCEPTIONS=0', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING'],
+        'CXXFLAGS': '$CCFLAGS /GS- /GR- /Gy',
         'DIALECTFLAGS': '/nologo',
-        'LIBS': 'WS2_32',
-        'LINKFLAGS': '/NOLOGO /SUBSYSTEM:CONSOLE /MACHINE:X86 /INCREMENTAL:NO /OPT:REF /OPT:ICF /SUBSYSTEM:CONSOLE',
+        'LINKFLAGS': '/NOLOGO /MACHINE:X86 /INCREMENTAL:NO /NXCOMPAT /IGNORE:4221 /OPT:REF',
         'PDB': '${TARGET}.pdb',
         'WARNINGFLAGS': '/W3 /WX /wd4355 /wd4800'
       },
       'dtoa': {
         'ARFLAGS': '/NOLOGO',
-        'CCFLAGS': '$DIALECTFLAGS $WARNINGFLAGS /O2 /MT',
+        'CCFLAGS': '$DIALECTFLAGS $WARNINGFLAGS /Ox /MT /Ob2 /Oi /Oy',
         'CCPDBFLAGS': '/Zi',
-        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING'],
-        'CXXFLAGS': '$CCFLAGS /EHsc /GS- /GR-',
+        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', '_HAS_EXCEPTIONS=0', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING'],
+        'CXXFLAGS': '$CCFLAGS /GS- /GR- /Gy',
         'DIALECTFLAGS': '/nologo',
-        'LIBS': 'WS2_32',
-        'LINKFLAGS': '/NOLOGO /SUBSYSTEM:CONSOLE /MACHINE:X86 /INCREMENTAL:NO /OPT:REF /OPT:ICF /SUBSYSTEM:CONSOLE',
+        'LINKFLAGS': '/NOLOGO /MACHINE:X86 /INCREMENTAL:NO /NXCOMPAT /IGNORE:4221 /OPT:REF',
         'PDB': '${TARGET}.pdb',
         'WARNINGFLAGS': '/WX /wd4018 /wd4244'
       },
       'jscre': {
         'ARFLAGS': '/NOLOGO',
-        'CCFLAGS': '$DIALECTFLAGS $WARNINGFLAGS /O2 /MT',
+        'CCFLAGS': '$DIALECTFLAGS $WARNINGFLAGS /Ox /MT /Ob2 /Oi /Oy',
         'CCPDBFLAGS': '/Zi',
-        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING', 'SUPPORT_UTF8', 'NO_RECURSE', 'SUPPORT_UCP'],
-        'CXXFLAGS': '$CCFLAGS /EHsc /GS- /GR-',
+        'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE', '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T', '_HAS_EXCEPTIONS=0', 'PCRE_STATIC', 'ENABLE_LOGGING_AND_PROFILING', 'SUPPORT_UTF8', 'NO_RECURSE', 'SUPPORT_UCP'],
+        'CXXFLAGS': '$CCFLAGS /GS- /GR- /Gy',
         'DIALECTFLAGS': '/nologo',
-        'LIBS': 'WS2_32',
-        'LINKFLAGS': '/NOLOGO /SUBSYSTEM:CONSOLE /MACHINE:X86 /INCREMENTAL:NO /OPT:REF /OPT:ICF /SUBSYSTEM:CONSOLE',
+        'LINKFLAGS': '/NOLOGO /MACHINE:X86 /INCREMENTAL:NO /NXCOMPAT /IGNORE:4221 /OPT:REF',
         'PDB': '${TARGET}.pdb',
-        'WARNINGFLAGS': '/WX /wd4003 /wd4005 /wd4018 /wd4133'
+        'WARNINGFLAGS': '/W3 /WX /wd4355 /wd4800'
       }
     }
   }
index 80519626bdd866c6e3517d51e27d02dd479ec786..3c2fc1217604ae0fa1a9a8c6d73835d6b09b7396 100644 (file)
@@ -2091,7 +2091,7 @@ bool v8::V8::Initialize() {
 
 
 const char* v8::V8::GetVersion() {
-  return "0.2.1 (130029)";
+  return "0.2.2 (130807)";
 }
 
 
index 418d568e64f8fee6ac6070481997f1a65af7d60b..55e9c45f0f9f120abedc55bdee552df94a2afd78 100644 (file)
@@ -45,7 +45,7 @@ namespace v8 { namespace internal {
 class Arguments BASE_EMBEDDED {
  public:
   Object*& operator[] (int index) {
-    ASSERT(0 <= index && index <= length_);
+    ASSERT(0 <= index && index < length_);
     return arguments_[-index];
   }
 
@@ -58,7 +58,7 @@ class Arguments BASE_EMBEDDED {
   }
 
   // Get the total number of arguments including the receiver.
-  int length() const { return length_ + 1; }
+  int length() const { return length_; }
 
  private:
   int length_;
index 4d9a46c4a9e437ad9f26e5e12cf410728416b90f..fbe8cceee61e65bdb19a7cddf5d0a85bbc32e4b4 100644 (file)
@@ -170,6 +170,14 @@ Operand::Operand(Register rm) {
 }
 
 
+bool Operand::is_reg() const {
+  return rm_.is_valid() &&
+         rs_.is(no_reg) &&
+         shift_op_ == LSL &&
+         shift_imm_ == 0;
+}
+
+
 void Assembler::CheckBuffer() {
   if (buffer_space() <= kGap) {
     GrowBuffer();
index d92e35c2874568d9e78e638532ff4756ba6753da..70e7b423c7ae5f979ec9c1a1773e4b8af479dd6d 100644 (file)
@@ -252,6 +252,7 @@ enum {
   B27 = 1 << 27,
 
   // Instruction bit masks
+  RdMask     = 15 << 12,  // in str instruction
   CondMask   = 15 << 28,
   OpCodeMask = 15 << 21,  // in data-processing instructions
   Imm24Mask  = (1 << 24) - 1,
@@ -261,6 +262,23 @@ enum {
 };
 
 
+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;
+// str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
+// register r is not encoded.
+static const Instr kPushRegPattern =
+    al | B26 | 4 | NegPreIndex | sp.code() * B16;
+// ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))
+// register r is not encoded.
+static const Instr kPopRegPattern =
+    al | B26 | L | 4 | PostIndex | sp.code() * B16;
+
 // spare_buffer_
 static const int kMinimalBufferSize = 4*KB;
 static byte* spare_buffer_ = NULL;
@@ -817,6 +835,23 @@ void Assembler::rsb(Register dst, Register src1, const Operand& src2,
 void Assembler::add(Register dst, Register src1, const Operand& src2,
                     SBit s, Condition cond) {
   addrmod1(cond | 4*B21 | s, src1, dst, src2);
+
+  // Eliminate pattern: push(r), pop()
+  //   str(src, MemOperand(sp, 4, NegPreIndex), al);
+  //   add(sp, sp, Operand(kPointerSize));
+  // Both instructions can be eliminated.
+  int pattern_size = 2 * kInstrSize;
+  if (FLAG_push_pop_elimination &&
+      last_bound_pos_ <= (pc_offset() - pattern_size) &&
+      reloc_info_writer.last_pc() <= (pc_ - pattern_size) &&
+      // pattern
+      instr_at(pc_ - 1 * kInstrSize) == kPopInstruction &&
+      (instr_at(pc_ - 2 * kInstrSize) & ~RdMask) == kPushRegPattern) {
+    pc_ -= 2 * kInstrSize;
+    if (FLAG_print_push_pop_elimination) {
+      PrintF("%x push(reg)/pop() eliminated\n", pc_offset());
+    }
+  }
 }
 
 
@@ -994,11 +1029,44 @@ void Assembler::msr(SRegisterFieldMask fields, const Operand& src,
 // Load/Store instructions
 void Assembler::ldr(Register dst, const MemOperand& src, Condition cond) {
   addrmod2(cond | B26 | L, dst, src);
+
+  // Eliminate pattern: push(r), pop(r)
+  //   str(r, MemOperand(sp, 4, NegPreIndex), al)
+  //   ldr(r, MemOperand(sp, 4, PostIndex), al)
+  // Both instructions can be eliminated.
+  int pattern_size = 2 * kInstrSize;
+  if (FLAG_push_pop_elimination &&
+      last_bound_pos_ <= (pc_offset() - pattern_size) &&
+      reloc_info_writer.last_pc() <= (pc_ - pattern_size) &&
+      // pattern
+      instr_at(pc_ - 1 * kInstrSize) == (kPopRegPattern | dst.code() * B12) &&
+      instr_at(pc_ - 2 * kInstrSize) == (kPushRegPattern | dst.code() * B12)) {
+    pc_ -= 2 * kInstrSize;
+    if (FLAG_print_push_pop_elimination) {
+      PrintF("%x push/pop (same reg) eliminated\n", pc_offset());
+    }
+  }
 }
 
 
 void Assembler::str(Register src, const MemOperand& dst, Condition cond) {
   addrmod2(cond | B26, src, dst);
+
+  // Eliminate pattern: pop(), push(r)
+  //     add sp, sp, #4 LeaveCC, al; str r, [sp, #-4], al
+  // ->  str r, [sp, 0], al
+  int pattern_size = 2 * kInstrSize;
+  if (FLAG_push_pop_elimination &&
+     last_bound_pos_ <= (pc_offset() - pattern_size) &&
+     reloc_info_writer.last_pc() <= (pc_ - pattern_size) &&
+     instr_at(pc_ - 1 * kInstrSize) == (kPushRegPattern | src.code() * B12) &&
+     instr_at(pc_ - 2 * kInstrSize) == kPopInstruction) {
+    pc_ -= 2 * kInstrSize;
+    emit(al | B26 | 0 | Offset | sp.code() * B16 | src.code() * B12);
+    if (FLAG_print_push_pop_elimination) {
+      PrintF("%x pop()/push(reg) eliminated\n", pc_offset());
+    }
+  }
 }
 
 
index e3f5692e21cd3c9ce450331f1512c8c58836bcaa..43bedfff7ef7fa88197eeb336bd8c266b2ec4f6a 100644 (file)
@@ -306,6 +306,11 @@ class Operand BASE_EMBEDDED {
   // rm <shift_op> rs
   explicit Operand(Register rm, ShiftOp shift_op, Register rs);
 
+  // Return true if this is a register operand.
+  INLINE(bool is_reg() const);
+
+  Register rm() const { return rm_; }
+
  private:
   Register rm_;
   Register rs_;
@@ -583,12 +588,16 @@ class Assembler : public Malloced {
   // Pseudo instructions
   void nop()  { mov(r0, Operand(r0)); }
 
-  void push(Register src, Condition cond = al) {
-    str(src, MemOperand(sp, 4, NegPreIndex), cond);
+  void push(Register src) {
+    str(src, MemOperand(sp, 4, NegPreIndex), al);
+  }
+
+  void pop(Register dst) {
+    ldr(dst, MemOperand(sp, 4, PostIndex), al);
   }
 
-  void pop(Register dst, Condition cond = al) {
-    ldr(dst, MemOperand(sp, 4, PostIndex), cond);
+  void pop() {
+    add(sp, sp, Operand(kPointerSize));
   }
 
   // Load effective address of memory operand x into register dst
index b3c8afbada4378372f3a41f6eebe3a876d7b3937..ebe0d6a0c5bcda0e7c1404d7e108377f329eb240 100644 (file)
@@ -435,10 +435,8 @@ const char* RelocInfo::RelocModeName(RelocMode rmode) {
   }
   return "unknown relocation type";
 }
-#endif  // ENABLE_DISASSEMBLER
 
 
-#ifdef DEBUG
 void RelocInfo::Print() {
   PrintF("%p  %s", pc_, RelocModeName(rmode_));
   if (rmode_ == comment) {
@@ -461,8 +459,10 @@ void RelocInfo::Print() {
 
   PrintF("\n");
 }
+#endif  // ENABLE_DISASSEMBLER
 
 
+#ifdef DEBUG
 void RelocInfo::Verify() {
   switch (rmode_) {
     case embedded_object:
index a149f8c54d0ea4be8511799245b17fe6849ddf79..9eb0cea522b5df2451385213cdbff38d72c3479f 100644 (file)
@@ -271,10 +271,10 @@ class RelocInfo BASE_EMBEDDED {
 #ifdef ENABLE_DISASSEMBLER
   // Printing
   static const char* RelocModeName(RelocMode rmode);
+  void Print();
 #endif  // ENABLE_DISASSEMBLER
 #ifdef DEBUG
   // Debugging
-  void Print();
   void Verify();
 #endif
 
index 4cb54f5827ac0f7ec93ab85c66a3e29600f978b2..323cb3dc107097af8fd5d98733be6b85e4c8dd40 100644 (file)
@@ -40,6 +40,10 @@ namespace v8 { namespace internal {
 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.
+  __ add(r0, r0, Operand(1));
   __ JumpToBuiltin(ExternalReference(id));
 }
 
@@ -50,10 +54,10 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
   __ EnterJSFrame(0);
 
   // Allocate the new receiver object.
-  __ push(r0);
   __ ldr(r0, MemOperand(pp, JavaScriptFrameConstants::kFunctionOffset));
+  __ push(r0);
   __ CallRuntime(Runtime::kNewObject, 1);
-  __ push(r0);  // empty TOS cache
+  __ push(r0);  // save the receiver
 
   // Push the function and the allocated receiver from the stack.
   __ ldr(r1, MemOperand(pp, JavaScriptFrameConstants::kFunctionOffset));
@@ -90,7 +94,7 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
 
   // Restore context from the frame and discard the function.
   __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  __ add(sp, sp, Operand(kPointerSize));
+  __ pop();
 
   // 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
@@ -273,20 +277,15 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
   __ add(fp, sp, Operand(-StandardFrameConstants::kContextOffset));
   __ mov(pp, Operand(ip));  // setup new parameter pointer
   // r0 is already set to 0 as spare slot to store caller code object during GC
+  __ push(r0);  // code pointer
 
   // Inlined EnterJSFrame ends here.
 
-  // Empty top-of-stack cache (code pointer).
-  __ push(r0);
-
   // Store the registers containing object pointers on the expression stack to
   // make sure that these are correctly updated during GC.
   // Use sp as base to push.
   __ CopyRegistersFromMemoryToStack(sp, pointer_regs);
 
-  // Empty top-of-stack cache (fake receiver).
-  __ push(r0);
-
 #ifdef DEBUG
   __ RecordComment("// Calling from debug break to runtime - come in - over");
 #endif
@@ -308,7 +307,7 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
 
   __ mov(sp, Operand(fp));  // respect ABI stack constraint
   __ ldm(ia, sp, pp.bit() | fp.bit() | sp.bit() | lr.bit());
-  __ add(sp, sp, Operand(kPointerSize));  // discard fake function
+  __ pop();  // discard fake function
 
   // Inlined ExitJSFrame ends here.
 
index e7a7e833e54a7ef21638a42e15ab294433185223..f61454a9113a8a51c1b326bf6131b68fdc61b610 100644 (file)
@@ -40,7 +40,10 @@ namespace v8 { namespace internal {
 void Builtins::Generate_Adaptor(MacroAssembler* masm,
                                 int argc,
                                 CFunctionId id) {
-  __ mov(eax, argc);
+  // 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);
   __ JumpToBuiltin(ExternalReference(id));
@@ -754,7 +757,6 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
   __ RecordComment("// Calling from debug break to runtime - come in - over");
 #endif
   __ Set(eax, Immediate(0));  // no arguments
-  __ push(eax);  // fake receiver - use NULL
   __ mov(Operand(ebx), Immediate(ExternalReference::debug_break()));
 
   CEntryDebugBreakStub ceb;
index 1f859b94ae679df6927d34295728ef6791f0bcc6..b51c39bd671209e4fae1a7c278e10abaa41feceb 100644 (file)
 
 namespace v8 { namespace internal {
 
+#ifdef DEBUG
+  DECLARE_bool(print_builtin_code);
+#endif  // DEBUG
+
+
 // ----------------------------------------------------------------------------
 // Support macros for defining builtins in C.
 // ----------------------------------------------------------------------------
@@ -58,6 +63,8 @@ namespace v8 { namespace internal {
 //
 // and they evaluate to undefined values if too few arguments were
 // passed to the builtin function invocation.
+//
+// __argc__ is the number of arguments including the receiver.
 // ----------------------------------------------------------------------------
 
 
@@ -82,7 +89,8 @@ namespace v8 { namespace internal {
       } else if (type == StackFrame::ARGUMENTS_ADAPTOR) {               \
         ArgumentsAdaptorFrame* frame =                                  \
             ArgumentsAdaptorFrame::cast(it.frame());                    \
-        __argc__ = frame->GetProvidedParametersCount();                 \
+        /* __argc__ includes the receiver. */                           \
+        __argc__ = frame->GetProvidedParametersCount() + 1;             \
         __argv__ = reinterpret_cast<Object**>(frame->pp()) - 1;         \
         it.Advance();                                                   \
         is_construct =                                                  \
@@ -107,17 +115,11 @@ namespace v8 { namespace internal {
   Object* a2 = BUILTIN_ARG(3);
 
 
-#define BUILTIN_VARARG(name, aidx0, aidxN)    \
-  BUILTIN_0(name);                            \
-  int aidx0 = 1;                              \
-  int aidxN = __argc__;                       \
-
-
 // Use an inline function to avoid evaluating the index (n) more than
 // once in the BUILTIN_ARG macro.
 static inline Object* __builtin_arg__(int n, int argc, Object** argv) {
   ASSERT(n >= 0);
-  return (argc >= n) ? argv[-n] : Heap::undefined_value();
+  return (argc > n) ? argv[-n] : Heap::undefined_value();
 }
 
 
@@ -181,7 +183,7 @@ BUILTIN_0(ArrayCode) {
 
   // Optimize the case where there is one argument and the argument is a
   // small smi.
-  if (__argc__ == 1) {
+  if (__argc__ == 2) {
     Object* obj = BUILTIN_ARG(1);
     if (obj->IsSmi()) {
       int len = Smi::cast(obj)->value();
@@ -195,26 +197,27 @@ BUILTIN_0(ArrayCode) {
     // Take the argument as the length.
     obj = array->Initialize(0);
     if (obj->IsFailure()) return obj;
-    if (__argc__ == 1) return array->SetElementsLength(BUILTIN_ARG(1));
+    if (__argc__ == 2) return array->SetElementsLength(BUILTIN_ARG(1));
   }
 
   // Optimize the case where there are no paramaters passed.
-  if (__argc__ == 0) return array->Initialize(4);
+  if (__argc__ == 1) return array->Initialize(4);
 
   // Take the arguments as elements.
-  int len = Smi::FromInt(__argc__)->value();
-  Object* obj = Heap::AllocateFixedArrayWithHoles(len);
+  int number_of_elements = __argc__ - 1;
+  Smi* len = Smi::FromInt(number_of_elements);
+  Object* obj = Heap::AllocateFixedArrayWithHoles(len->value());
   if (obj->IsFailure()) return obj;
   FixedArray* elms = FixedArray::cast(obj);
   FixedArray::WriteBarrierMode mode = elms->GetWriteBarrierMode();
   // Fill in the content
-  for (int index = 0; index < __argc__; index++) {
+  for (int index = 0; index < number_of_elements; index++) {
     elms->set(index, BUILTIN_ARG(index+1), mode);
   }
 
   // Set length and elements on the array.
   array->set_elements(FixedArray::cast(obj));
-  array->set_length(Smi::FromInt(__argc__));
+  array->set_length(len);
 
   return array;
 }
@@ -229,12 +232,12 @@ BUILTIN_0(ArrayPush) {
   int len = Smi::cast(array->length())->value();
 
   // Set new length.
-  int new_length = len + __argc__;
+  int new_length = len + __argc__ - 1;
   FixedArray* elms = FixedArray::cast(array->elements());
 
   if (new_length <= elms->length()) {
     // Backing storage has extra space for the provided values.
-    for (int index = 0; index < __argc__; index++) {
+    for (int index = 0; index < __argc__ - 1; index++) {
       elms->set(index + len, BUILTIN_ARG(index+1));
     }
   } else {
@@ -247,7 +250,7 @@ BUILTIN_0(ArrayPush) {
     // Fill out the new array with old elements.
     for (int i = 0; i < len; i++) new_elms->set(i, elms->get(i), mode);
     // Add the provided values.
-    for (int index = 0; index < __argc__; index++) {
+    for (int index = 0; index < __argc__ - 1; index++) {
       new_elms->set(index + len, BUILTIN_ARG(index+1), mode);
     }
     // Set the new backing storage.
@@ -327,7 +330,7 @@ static inline Object* TypeCheck(int argc,
   if (args_obj->IsUndefined()) return holder;
   FixedArray* args = FixedArray::cast(args_obj);
   int length = args->length();
-  if (argc < length) length = argc;
+  if (argc <= length) length = argc - 1;
   for (int i = 0; i < length; i++) {
     Object* argtype = args->get(i);
     if (argtype->IsUndefined()) continue;
@@ -405,7 +408,7 @@ BUILTIN_0(HandleApiCall) {
         callee,
         is_construct,
         reinterpret_cast<void**>(__argv__ - 1),
-        __argc__);
+        __argc__ - 1);
 
     v8::Handle<v8::Value> value;
     {
@@ -467,7 +470,7 @@ BUILTIN_0(HandleApiCallAsFunction) {
         callee,
         is_construct,
         reinterpret_cast<void**>(__argv__ - 1),
-        __argc__);
+        __argc__ - 1);
     v8::Handle<v8::Value> value;
     {
       // Leaving JavaScript.
@@ -692,6 +695,13 @@ void Builtins::Setup(bool create_heap_objects) {
       // Log the event and add the code to the builtins array.
       LOG(CodeCreateEvent("Builtin", Code::cast(code), functions[i].s_name));
       builtins_[i] = code;
+#ifdef DEBUG
+      if (FLAG_print_builtin_code) {
+        PrintF("Builtin: %s\n", functions[i].s_name);
+        code->Print();
+        PrintF("\n");
+      }
+#endif
     } else {
       // Deserializing. The values will be filled in during IterateBuiltins.
       builtins_[i] = NULL;
index b198663511fe3ea0ba56453bbd10dd238da4d7d1..b4f7c289cde58b5d4b0db93e09d0a6f647f19136 100644 (file)
@@ -69,6 +69,10 @@ class CodeStub BASE_EMBEDDED {
 
   virtual ~CodeStub() {}
 
+ protected:
+  static const int kMajorBits = 5;
+  static const int kMinorBits = kBitsPerPointer - kMajorBits - kSmiTagSize;
+
  private:
   // Generates the assembler code for the stub.
   virtual void Generate(MacroAssembler* masm) = 0;
@@ -93,9 +97,6 @@ class CodeStub BASE_EMBEDDED {
 
   bool AllowsStubCalls() { return MajorKey() <= RecordWrite; }
 
-  static const int kMajorBits = 5;
-  static const int kMinorBits = kBitsPerPointer - kMajorBits - kSmiTagSize;
-
   class MajorKeyBits: public BitField<uint32_t, 0, kMajorBits> {};
   class MinorKeyBits: public BitField<uint32_t, kMajorBits, kMinorBits> {};
 
index 4f44583fe729574e6209d334d47e707c99c64886..004c3627a57af9dd8ebfd04bc8d2ecd9e2891266 100644 (file)
@@ -55,10 +55,10 @@ class ParameterCount BASE_EMBEDDED {
   }
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(ParameterCount);
-
   const Register reg_;
   const int immediate_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ParameterCount);
 };
 
 
index 451329125286b9f349c87a1c04ebba79954c7d73..da7c73f57da077d6f48bf117448e3d7a6c437c13 100644 (file)
@@ -41,11 +41,14 @@ 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_code, false, "print generated code");
 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,
@@ -233,7 +236,7 @@ class ArmCodeGenerator: public CodeGenerator {
     AccessReference(ref, CodeGenState::INIT_CONST);
   }
 
-  void ToBoolean(Register reg, Label* true_target, Label* false_target);
+  void ToBoolean(Label* true_target, Label* false_target);
 
 
   // Access property from the reference (must be at the TOS).
@@ -303,10 +306,13 @@ class ArmCodeGenerator: public CodeGenerator {
 Handle<Code> ArmCodeGenerator::MakeCode(FunctionLiteral* flit,
                                         Handle<Script> script,
                                         bool is_eval) {
+#ifdef ENABLE_DISASSEMBLER
+  bool print_code = FLAG_print_code && !Bootstrapper::IsActive();
+#endif  // ENABLE_DISASSEMBLER
+
 #ifdef DEBUG
   bool print_source = false;
   bool print_ast = false;
-  bool print_code = false;
   const char* ftype;
 
   if (Bootstrapper::IsActive()) {
@@ -317,7 +323,6 @@ Handle<Code> ArmCodeGenerator::MakeCode(FunctionLiteral* flit,
   } else {
     print_source = FLAG_print_source;
     print_ast = FLAG_print_ast;
-    print_code = FLAG_print_code;
     ftype = "user-defined";
   }
 
@@ -358,7 +363,7 @@ Handle<Code> ArmCodeGenerator::MakeCode(FunctionLiteral* flit,
   // Add unresolved entries in the code to the fixup list.
   Bootstrapper::AddFixup(*code, cgen.masm());
 
-#ifdef DEBUG
+#ifdef ENABLE_DISASSEMBLER
   if (print_code) {
     // Print the source code if available.
     if (!script->IsUndefined() && !script->source()->IsUndefined()) {
@@ -374,9 +379,9 @@ Handle<Code> ArmCodeGenerator::MakeCode(FunctionLiteral* flit,
       PrintF("\n\n");
     }
     PrintF("--- Code ---\n");
-    code->Print();
+    code->Disassemble();
   }
-#endif  // DEBUG
+#endif  // ENABLE_DISASSEMBLER
 
   return code;
 }
@@ -396,8 +401,7 @@ ArmCodeGenerator::ArmCodeGenerator(int buffer_size,
 
 // Calling conventions:
 
-// r0: always contains top-of-stack (TOS), but in case of a call it's
-//     the number of arguments
+// r0: the number of arguments
 // fp: frame pointer
 // sp: stack pointer
 // pp: caller's parameter pointer
@@ -435,20 +439,18 @@ void ArmCodeGenerator::GenCode(FunctionLiteral* fun) {
     // Allocate space for locals and initialize them.
     if (scope->num_stack_slots() > 0) {
       Comment cmnt(masm_, "[ allocate space for locals");
-      // Pushing the first local materializes the code slot on the stack
-      // (formerly stored in tos register r0).
-      __ Push(Operand(Factory::undefined_value()));
-      // The remaining locals are pushed using the fact that r0 (tos)
-      // already contains the undefined value.
-      for (int i = 1; i < scope->num_stack_slots(); i++) {
-        __ push(r0);
+      // Initialize stack slots with 'undefined' value.
+      __ mov(ip, Operand(Factory::undefined_value()));
+      for (int i = 0; i < scope->num_stack_slots(); i++) {
+        __ push(ip);
       }
     }
 
     if (scope->num_heap_slots() > 0) {
       // Allocate local context.
       // Get outer context and create a new context based on it.
-      __ Push(FunctionOperand());
+      __ ldr(r0, FunctionOperand());
+      __ push(r0);
       __ CallRuntime(Runtime::kNewContext, 1);  // r0 holds the result
 
       if (kDebug) {
@@ -458,7 +460,6 @@ void ArmCodeGenerator::GenCode(FunctionLiteral* fun) {
         __ stop("NewContext: r0 is expected to be the same as cp");
         __ bind(&verified_true);
       }
-      __ pop(r0);  // restore TOS
       // Update context local.
       __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
     }
@@ -505,8 +506,10 @@ void ArmCodeGenerator::GenCode(FunctionLiteral* fun) {
       Comment cmnt(masm_, "[ allocate arguments object");
       {
         Reference target(this, scope->arguments());
-        __ Push(FunctionOperand());
+        __ ldr(r0, FunctionOperand());
+        __ push(r0);
         __ CallRuntime(Runtime::kNewArguments, 1);
+        __ push(r0);
         SetValue(&target);
       }
       // The value of arguments must also be stored in .arguments.
@@ -528,13 +531,21 @@ void ArmCodeGenerator::GenCode(FunctionLiteral* fun) {
       scope->VisitIllegalRedeclaration(this);
     } else {
       Comment cmnt(masm_, "[ declarations");
+      // ProcessDeclarations calls DeclareGlobals indirectly
       ProcessDeclarations(scope->declarations());
+
       // Bail out if a stack-overflow exception occured when
       // processing declarations.
       if (HasStackOverflow()) return;
     }
 
-    if (FLAG_trace) __ CallRuntime(Runtime::kTraceEnter, 1);
+    if (FLAG_trace) {
+      // Push a valid value as the parameter. The runtime call only uses
+      // it as the return value to indicate non-failure.
+      __ mov(r0, Operand(Smi::FromInt(0)));
+      __ push(r0);
+      __ CallRuntime(Runtime::kTraceEnter, 1);
+    }
     CheckStack();
 
     // Compile the body of the function in a vanilla state. Don't
@@ -546,7 +557,13 @@ void ArmCodeGenerator::GenCode(FunctionLiteral* fun) {
       bool is_builtin = Bootstrapper::IsActive();
       bool should_trace =
           is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls;
-      if (should_trace) __ CallRuntime(Runtime::kDebugTrace, 1);
+      if (should_trace) {
+        // Push a valid value as the parameter. The runtime call only uses
+        // it as the return value to indicate non-failure.
+        __ mov(r0, Operand(Smi::FromInt(0)));
+        __ push(r0);
+        __ CallRuntime(Runtime::kDebugTrace, 1);
+      }
 #endif
       VisitStatements(body);
     }
@@ -560,9 +577,16 @@ void ArmCodeGenerator::GenCode(FunctionLiteral* fun) {
   // fp: frame pointer
   // pp: parameter pointer
   // cp: callee's context
-  __ Push(Operand(Factory::undefined_value()));
+  __ mov(r0, Operand(Factory::undefined_value()));
+
   __ bind(&function_return_);
-  if (FLAG_trace) __ CallRuntime(Runtime::kTraceExit, 1);
+  if (FLAG_trace) {
+    // Push the return value on the stack as the parameter.
+    // Runtime::TraceExit returns the parameter as it is.
+    __ push(r0);
+    __ CallRuntime(Runtime::kTraceExit, 1);
+  }
+
   ExitJSFrame();
 
   // Code generation state must be reset.
@@ -629,10 +653,10 @@ MemOperand ArmCodeGenerator::SlotOperand(Slot* slot, Register tmp) {
 }
 
 
-// Loads a value on TOS. If it is a boolean value, the result may have been
-// (partially) translated into branches, or it may have set the condition code
-// register. If force_cc is set, the value is forced to set the condition code
-// register and no value is pushed. If the condition code register was set,
+// Loads a value on the stack. If it is a boolean value, the result may have
+// been (partially) translated into branches, or it may have set the condition
+// code register. If force_cc is set, the value is forced to set the condition
+// code register and no value is pushed. If the condition code register was set,
 // has_cc() is true and cc_reg_ contains the condition to test for 'true'.
 void ArmCodeGenerator::LoadCondition(Expression* x,
                                      CodeGenState::AccessType access,
@@ -649,11 +673,8 @@ void ArmCodeGenerator::LoadCondition(Expression* x,
   Visit(x);
   state_ = old_state;
   if (force_cc && !has_cc()) {
-    // Pop the TOS from the stack and convert it to a boolean in the
-    // condition code register.
-    __ mov(r1, Operand(r0));
-    __ pop(r0);
-    ToBoolean(r1, true_target, false_target);
+    // Convert the TOS value to a boolean in the condition code register.
+    ToBoolean(true_target, false_target);
   }
   ASSERT(has_cc() || !force_cc);
 }
@@ -671,10 +692,12 @@ void ArmCodeGenerator::Load(Expression* x, CodeGenState::AccessType access) {
     // convert cc_reg_ into a bool
     Label loaded, materialize_true;
     __ b(cc_reg_, &materialize_true);
-    __ Push(Operand(Factory::false_value()));
+    __ mov(r0, Operand(Factory::false_value()));
+    __ push(r0);
     __ b(&loaded);
     __ bind(&materialize_true);
-    __ Push(Operand(Factory::true_value()));
+    __ mov(r0, Operand(Factory::true_value()));
+    __ push(r0);
     __ bind(&loaded);
     cc_reg_ = al;
   }
@@ -689,7 +712,8 @@ void ArmCodeGenerator::Load(Expression* x, CodeGenState::AccessType access) {
     // reincarnate "true", if necessary
     if (true_target.is_linked()) {
       __ bind(&true_target);
-      __ Push(Operand(Factory::true_value()));
+      __ mov(r0, Operand(Factory::true_value()));
+      __ push(r0);
     }
     // if both "true" and "false" need to be reincarnated,
     // jump across code for "false"
@@ -698,7 +722,8 @@ void ArmCodeGenerator::Load(Expression* x, CodeGenState::AccessType access) {
     // reincarnate "false", if necessary
     if (false_target.is_linked()) {
       __ bind(&false_target);
-      __ Push(Operand(Factory::false_value()));
+      __ mov(r0, Operand(Factory::false_value()));
+      __ push(r0);
     }
     // everything is loaded at this point
     __ bind(&loaded);
@@ -708,7 +733,8 @@ void ArmCodeGenerator::Load(Expression* x, CodeGenState::AccessType access) {
 
 
 void ArmCodeGenerator::LoadGlobal() {
-  __ Push(GlobalObject());
+  __ ldr(r0, GlobalObject());
+  __ push(r0);
 }
 
 
@@ -776,6 +802,7 @@ void ArmCodeGenerator::LoadReference(Reference* ref) {
   } else {
     Load(e);
     __ CallRuntime(Runtime::kThrowReferenceError, 1);
+    __ push(r0);
   }
 }
 
@@ -785,7 +812,9 @@ void ArmCodeGenerator::UnloadReference(Reference* ref) {
   if (size <= 0) {
     // Do nothing. No popping is necessary.
   } else {
+    __ pop(r0);
     __ add(sp, sp, Operand(size * kPointerSize));
+    __ push(r0);
   }
 }
 
@@ -805,43 +834,38 @@ void ArmCodeGenerator::AccessReference(Reference* ref,
 // ECMA-262, section 9.2, page 30: ToBoolean(). Convert the given
 // register to a boolean in the condition code register. The code
 // may jump to 'false_target' in case the register converts to 'false'.
-void ArmCodeGenerator::ToBoolean(Register reg,
-                                 Label* true_target,
+void ArmCodeGenerator::ToBoolean(Label* true_target,
                                  Label* false_target) {
-  // Note: The generated code snippet cannot change 'reg'.
+  // Note: The generated code snippet does not change stack variables.
   //       Only the condition code should be set.
+  __ pop(r0);
 
   // Fast case checks
 
-  // Check if reg is 'false'.
-  __ cmp(reg, Operand(Factory::false_value()));
+  // Check if the value is 'false'.
+  __ cmp(r0, Operand(Factory::false_value()));
   __ b(eq, false_target);
 
-  // Check if reg is 'true'.
-  __ cmp(reg, Operand(Factory::true_value()));
+  // Check if the value is 'true'.
+  __ cmp(r0, Operand(Factory::true_value()));
   __ b(eq, true_target);
 
-  // Check if reg is 'undefined'.
-  __ cmp(reg, Operand(Factory::undefined_value()));
+  // Check if the value is 'undefined'.
+  __ cmp(r0, Operand(Factory::undefined_value()));
   __ b(eq, false_target);
 
-  // Check if reg is a smi.
-  __ cmp(reg, Operand(Smi::FromInt(0)));
+  // Check if the value is a smi.
+  __ cmp(r0, Operand(Smi::FromInt(0)));
   __ b(eq, false_target);
-  __ tst(reg, Operand(kSmiTagMask));
+  __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, true_target);
 
   // Slow case: call the runtime.
   __ push(r0);
-  if (r0.is(reg)) {
-    __ CallRuntime(Runtime::kToBool, 1);
-  } else {
-    __ mov(r0, Operand(reg));
-    __ CallRuntime(Runtime::kToBool, 1);
-  }
+  __ CallRuntime(Runtime::kToBool, 1);
+
   // Convert result (r0) to condition code
   __ cmp(r0, Operand(Factory::false_value()));
-  __ pop(r0);
 
   cc_reg_ = ne;
 }
@@ -865,9 +889,11 @@ class GetPropertyStub : public CodeStub {
 
 
 void GetPropertyStub::Generate(MacroAssembler* masm) {
+  // sp[0]: key
+  // sp[1]: receiver
   Label slow, fast;
-  // Get the object from the stack.
-  __ ldr(r1, MemOperand(sp, 1 * kPointerSize));  // 1 ~ key
+  // Get the key and receiver object from the stack.
+  __ ldm(ia, sp, r0.bit() | r1.bit());
   // Check that the key is a smi.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(ne, &slow);
@@ -903,8 +929,7 @@ void GetPropertyStub::Generate(MacroAssembler* masm) {
   __ ldm(ia, sp, r0.bit() | r1.bit());
   __ stm(db_w, sp, r0.bit() | r1.bit());
   // Do tail-call to runtime routine.
-  __ mov(r0, Operand(1));  // not counting receiver
-  __ JumpToBuiltin(ExternalReference(Runtime::kGetProperty));
+  __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2);
 
   // Fast case: Do the load.
   __ bind(&fast);
@@ -932,10 +957,15 @@ class SetPropertyStub : public CodeStub {
 };
 
 
+
 void SetPropertyStub::Generate(MacroAssembler* masm) {
+  // r0 : value
+  // sp[0] : key
+  // sp[1] : receiver
+
   Label slow, fast, array, extra, exit;
   // Get the key and the object from the stack.
-  __ ldm(ia, sp, r1.bit() | r3.bit());  // r0 == value, r1 == key, r3 == object
+  __ ldm(ia, sp, r1.bit() | r3.bit());  // r1 = key, r3 = receiver
   // Check that the key is a smi.
   __ tst(r1, Operand(kSmiTagMask));
   __ b(ne, &slow);
@@ -970,13 +1000,11 @@ void SetPropertyStub::Generate(MacroAssembler* masm) {
 
 
   // Slow case: Push extra copies of the arguments (3).
-  // r0 == value
   __ bind(&slow);
   __ ldm(ia, sp, r1.bit() | r3.bit());  // r0 == value, r1 == key, r3 == object
   __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
   // Do tail-call to runtime routine.
-  __ mov(r0, Operand(2));  // not counting receiver
-  __ JumpToBuiltin(ExternalReference(Runtime::kSetProperty));
+  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
 
 
   // Extra capacity case: Check if there is extra capacity to
@@ -1067,12 +1095,14 @@ class GenericBinaryOpStub : public CodeStub {
 
 
 void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
+  // r1 : x
+  // r0 : y
+  // result : r0
+
   switch (op_) {
     case Token::ADD: {
       Label slow, exit;
       // fast path
-      // Get x (y is on TOS, i.e., r0).
-      __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
       __ orr(r2, r1, Operand(r0));  // r2 = x | y;
       __ add(r0, r1, Operand(r0), SetCC);  // add y optimistically
       // go slow-path in case of overflow
@@ -1084,6 +1114,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
       // slow path
       __ bind(&slow);
       __ sub(r0, r0, Operand(r1));  // revert optimistic add
+      __ push(r1);
       __ push(r0);
       __ mov(r0, Operand(1));  // set number of arguments
       __ InvokeBuiltin("ADD", 1, JUMP_JS);
@@ -1095,7 +1126,6 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
     case Token::SUB: {
       Label slow, exit;
       // fast path
-      __ ldr(r1, MemOperand(sp, 0 * kPointerSize));  // get x
       __ orr(r2, r1, Operand(r0));  // r2 = x | y;
       __ sub(r3, r1, Operand(r0), SetCC);  // subtract y optimistically
       // go slow-path in case of overflow
@@ -1107,6 +1137,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
       __ b(eq, &exit);
       // slow path
       __ bind(&slow);
+      __ push(r1);
       __ push(r0);
       __ mov(r0, Operand(1));  // set number of arguments
       __ InvokeBuiltin("SUB", 1, JUMP_JS);
@@ -1117,7 +1148,6 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
 
     case Token::MUL: {
       Label slow, exit;
-      __ ldr(r1, MemOperand(sp, 0 * kPointerSize));  // get x
       // tag check
       __ orr(r2, r1, Operand(r0));  // r2 = x | y;
       ASSERT(kSmiTag == 0);  // adjust code below
@@ -1137,6 +1167,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
       __ b(ne, &exit);
       // slow case
       __ bind(&slow);
+      __ push(r1);
       __ push(r0);
       __ mov(r0, Operand(1));  // set number of arguments
       __ InvokeBuiltin("MUL", 1, JUMP_JS);
@@ -1146,7 +1177,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
     }
     default: UNREACHABLE();
   }
-  masm->StubReturn(2);
+  __ Ret();
 }
 
 
@@ -1221,8 +1252,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
   __ b(hs, &within_limit);
   // Do tail-call to runtime routine.
   __ push(r0);
-  __ mov(r0, Operand(0));  // not counting receiver (i.e. flushed TOS)
-  __ JumpToBuiltin(ExternalReference(Runtime::kStackGuard));
+  __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
   __ bind(&within_limit);
 
   masm->StubReturn(1);
@@ -1385,7 +1415,7 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {
   __ mov(r2, Operand(external_caught));
   __ str(r0, MemOperand(r2));
 
-  // Set pending exception and TOS to out of memory exception.
+  // Set pending exception and r0 to out of memory exception.
   Failure* out_of_memory = Failure::OutOfMemoryException();
   __ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
   __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address)));
@@ -1414,17 +1444,19 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
                               bool do_gc,
                               bool do_restore) {
   // r0: result parameter for PerformGC, if any
-  // r4: number of arguments  (C callee-saved)
+  // r4: number of arguments including receiver  (C callee-saved)
   // r5: pointer to builtin function  (C callee-saved)
 
   if (do_gc) {
     __ Call(FUNCTION_ADDR(Runtime::PerformGC), runtime_entry);  // passing r0
   }
 
-  // call C built-in
-  __ mov(r0, Operand(r4));  // a0 = argc
+  // Call C built-in.
+  // r0 = argc.
+  __ mov(r0, Operand(r4));
+  // r1 = argv.
   __ add(r1, fp, Operand(r4, LSL, kPointerSizeLog2));
-  __ add(r1, r1, Operand(ExitFrameConstants::kPPDisplacement));  // a1 = argv
+  __ add(r1, r1, Operand(ExitFrameConstants::kPPDisplacement - kPointerSize));
 
   // TODO(1242173): To let the GC traverse the return address of the exit
   // frames, we need to know where the return address is. Right now,
@@ -1512,7 +1544,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
 
 void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
   // Called from JavaScript; parameters are on stack as if calling JS function
-  // r0: number of arguments
+  // r0: number of arguments including receiver
   // r1: pointer to builtin function
   // fp: frame pointer  (restored after C call)
   // sp: stack pointer  (restored as callee's pp after C call)
@@ -1527,9 +1559,8 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
   // Enter C frame
   // Compute parameter pointer before making changes and save it as ip register
   // so that it is restored as sp register on exit, thereby popping the args.
-  // ip = sp + kPointerSize*(args_len+1);  // +1 for receiver
+  // ip = sp + kPointerSize*args_len;
   __ add(ip, sp, Operand(r0, LSL, kPointerSizeLog2));
-  __ add(ip, ip, Operand(kPointerSize));
 
   // 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
@@ -1701,7 +1732,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   __ str(r3, MemOperand(ip));
 
   // Remove constructor mark.
-  __ add(sp, sp, Operand(kPointerSize));
+  __ pop();
 
   // Restore callee-saved registers, sp, and return.
 #ifdef DEBUG
@@ -1759,8 +1790,7 @@ void ArgumentsAccessStub::Generate(MacroAssembler* masm) {
     // by calling the runtime system.
     __ bind(&slow);
     __ push(r0);
-    __ mov(r0, Operand(0));  // not counting receiver
-    __ JumpToBuiltin(ExternalReference(Runtime::kGetArgumentsProperty));
+    __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
   }
 }
 
@@ -1787,14 +1817,10 @@ void ArmCodeGenerator::AccessReferenceProperty(
     Literal* literal = key->AsLiteral();
     Handle<String> name(String::cast(*literal->handle()));
 
-    // Loading adds a value to the stack; push the TOS to prepare.
-    if (is_load) __ push(r0);
-
-    // Setup the name register.
-    __ mov(r2, Operand(name));
-
     // 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) {
@@ -1803,49 +1829,59 @@ void ArmCodeGenerator::AccessReferenceProperty(
       } else {
         __ Call(ic, code_target);
       }
+
     } else {
+      __ pop(r0);  // value
+      // Setup the name register.
+      __ mov(r2, Operand(name));
       Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
       __ Call(ic, code_target);
     }
-    return;
-  }
 
-  // Access keyed property.
-  ASSERT(type == Reference::KEYED);
-
-  if (is_load) {
-    __ push(r0);  // empty tos
-    // TODO(1224671): Implement inline caching for keyed loads as on ia32.
-    GetPropertyStub stub;
-    __ CallStub(&stub);
   } else {
-    SetPropertyStub stub;
-    __ CallStub(&stub);
+    // 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);
+    }
   }
+  __ push(r0);
 }
 
 
 void ArmCodeGenerator::GenericBinaryOperation(Token::Value op) {
+  // sp[0] : y
+  // sp[1] : x
+  // result : r0
+
   // Stub is entered with a call: 'return address' is in lr.
   switch (op) {
     case Token::ADD:  // fall through.
     case Token::SUB:  // fall through.
     case Token::MUL: {
+      __ pop(r0);  // r0 : y
+      __ pop(r1);  // r1 : x
       GenericBinaryOpStub stub(op);
       __ CallStub(&stub);
       break;
     }
 
     case Token::DIV: {
-      __ push(r0);
-      __ mov(r0, Operand(1));  // set number of arguments
+      __ mov(r0, Operand(1));
       __ InvokeBuiltin("DIV", 1, CALL_JS);
       break;
     }
 
     case Token::MOD: {
-      __ push(r0);
-      __ mov(r0, Operand(1));  // set number of arguments
+      __ mov(r0, Operand(1));
       __ InvokeBuiltin("MOD", 1, CALL_JS);
       break;
     }
@@ -1854,6 +1890,7 @@ void ArmCodeGenerator::GenericBinaryOperation(Token::Value op) {
     case Token::BIT_AND:
     case Token::BIT_XOR: {
       Label slow, exit;
+      __ pop(r0);  // get y
       __ pop(r1);  // get x
       // tag check
       __ orr(r2, r1, Operand(r0));  // r2 = x | y;
@@ -1885,7 +1922,7 @@ void ArmCodeGenerator::GenericBinaryOperation(Token::Value op) {
     case Token::SHR:
     case Token::SAR: {
       Label slow, exit;
-      __ mov(r1, Operand(r0));  // get y
+      __ pop(r1);  // get y
       __ pop(r0);  // get x
       // tag check
       __ orr(r2, r1, Operand(r0));  // r2 = x | y;
@@ -1928,15 +1965,15 @@ void ArmCodeGenerator::GenericBinaryOperation(Token::Value op) {
 
         default: UNREACHABLE();
       }
-      // tag result and store it in TOS (r0)
+      // tag result and store it in r0
       ASSERT(kSmiTag == 0);  // adjust code below
       __ mov(r0, Operand(r3, LSL, kSmiTagSize));
       __ b(&exit);
       // slow case
       __ bind(&slow);
       __ push(r0);  // restore stack
-      __ mov(r0, Operand(r1));
-      __ Push(Operand(1));  // 1 argument (not counting receiver).
+      __ push(r1);
+      __ mov(r0, Operand(1));  // 1 argument (not counting receiver).
       switch (op) {
         case Token::SAR: __ InvokeBuiltin("SAR", 1, CALL_JS); break;
         case Token::SHR: __ InvokeBuiltin("SHR", 1, CALL_JS); break;
@@ -1948,8 +1985,9 @@ void ArmCodeGenerator::GenericBinaryOperation(Token::Value op) {
     }
 
     case Token::COMMA:
+      __ pop(r0);
       // simply discard left value
-      __ add(sp, sp, Operand(kPointerSize));
+      __ pop();
       break;
 
     default:
@@ -1960,8 +1998,6 @@ void ArmCodeGenerator::GenericBinaryOperation(Token::Value op) {
 }
 
 
-
-
 void ArmCodeGenerator::SmiOperation(Token::Value op,
                                     Handle<Object> value,
                                     bool reversed) {
@@ -1972,9 +2008,12 @@ void ArmCodeGenerator::SmiOperation(Token::Value op,
   // code size is increased by ~1% (measured on a combination of
   // different benchmarks).
 
+  // sp[0] : operand
+
   ASSERT(value->IsSmi());
 
   Label exit;
+  __ pop(r0);
 
   switch (op) {
     case Token::ADD: {
@@ -2015,10 +2054,13 @@ void ArmCodeGenerator::SmiOperation(Token::Value op,
 
     default:
       if (!reversed) {
-        __ Push(Operand(value));
+        __ push(r0);
+        __ mov(r0, Operand(value));
+        __ push(r0);
       } else {
         __ mov(ip, Operand(value));
         __ push(ip);
+        __ push(r0);
       }
       GenericBinaryOperation(op);
       break;
@@ -2029,6 +2071,10 @@ void ArmCodeGenerator::SmiOperation(Token::Value op,
 
 
 void ArmCodeGenerator::Comparison(Condition cc, bool strict) {
+  // sp[0] : y
+  // sp[1] : x
+  // result : cc register
+
   // Strict only makes sense for equality comparisons.
   ASSERT(!strict || cc == eq);
 
@@ -2036,9 +2082,10 @@ void ArmCodeGenerator::Comparison(Condition cc, bool strict) {
   // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order.
   if (cc == gt || cc == le) {
     cc = ReverseCondition(cc);
-    __ mov(r1, Operand(r0));
+    __ pop(r1);
     __ pop(r0);
   } else {
+    __ pop(r0);
     __ pop(r1);
   }
   __ orr(r2, r0, Operand(r1));
@@ -2063,13 +2110,15 @@ void ArmCodeGenerator::Comparison(Condition cc, bool strict) {
       ASSERT(cc == gt || cc == ge);  // remaining cases
       ncr = LESS;
     }
-    __ Push(Operand(Smi::FromInt(ncr)));
+    __ push(r0);
+    __ mov(r0, Operand(Smi::FromInt(ncr)));
     argc = 2;
   }
 
   // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
   // tagged as a small integer.
-  __ Push(Operand(argc));
+  __ push(r0);
+  __ mov(r0, Operand(argc));
   __ InvokeBuiltin(native, argc, CALL_JS);
   __ cmp(r0, Operand(0));
   __ b(&exit);
@@ -2079,7 +2128,6 @@ void ArmCodeGenerator::Comparison(Condition cc, bool strict) {
   __ cmp(r1, Operand(r0));
 
   __ bind(&exit);
-  __ pop(r0);  // be careful not to destroy the cc register
   cc_reg_ = cc;
 }
 
@@ -2106,10 +2154,6 @@ class CallFunctionStub: public CodeStub {
 
 void CallFunctionStub::Generate(MacroAssembler* masm) {
   Label slow;
-
-  // Flush the TOS cache
-  masm->push(r0);
-
   // Get the function to call from the stack.
   // function, receiver [, arguments]
   masm->ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize));
@@ -2136,12 +2180,13 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
 }
 
 
-// Call the function just below TOS on the stack with the given
-// arguments. The receiver is the TOS.
+// Call the function on the stack with the given arguments.
 void ArmCodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
                                          int position) {
   // Push the arguments ("left-to-right") on the stack.
-  for (int i = 0; i < args->length(); i++) Load(args->at(i));
+  for (int i = 0; i < args->length(); i++) {
+    Load(args->at(i));
+  }
 
   // Record the position for debugging purposes.
   __ RecordPosition(position);
@@ -2152,7 +2197,7 @@ void ArmCodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
 
   // Restore context and pop function from the stack.
   __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  __ add(sp, sp, Operand(kPointerSize));  // discard
+  __ pop();  // discard the TOS
 }
 
 
@@ -2183,13 +2228,13 @@ void ArmCodeGenerator::VisitBlock(Block* node) {
 
 
 void ArmCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
-  __ Push(Operand(pairs));
-  __ Push(Operand(cp));
-  __ Push(Operand(Smi::FromInt(is_eval() ? 1 : 0)));
+  __ mov(r0, Operand(pairs));
+  __ push(r0);
+  __ push(cp);
+  __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
+  __ push(r0);
   __ CallRuntime(Runtime::kDeclareGlobals, 3);
-
-  // Get rid of return value.
-  __ pop(r0);
+  // The result is discarded.
 }
 
 
@@ -2207,27 +2252,30 @@ void ArmCodeGenerator::VisitDeclaration(Declaration* node) {
     // during variable resolution and must have mode DYNAMIC.
     ASSERT(var->mode() == Variable::DYNAMIC);
     // For now, just do a runtime call.
-    __ Push(Operand(cp));
-    __ Push(Operand(var->name()));
+    __ push(cp);
+    __ mov(r0, Operand(var->name()));
+    __ push(r0);
     // Declaration nodes are always declared in only two modes.
     ASSERT(node->mode() == Variable::VAR || node->mode() == Variable::CONST);
     PropertyAttributes attr = node->mode() == Variable::VAR ? NONE : READ_ONLY;
-    __ Push(Operand(Smi::FromInt(attr)));
+    __ mov(r0, Operand(Smi::FromInt(attr)));
+    __ push(r0);
     // Push initial value, if any.
     // Note: For variables we must not push an initial value (such as
     // 'undefined') because we may have a (legal) redeclaration and we
     // must not destroy the current value.
     if (node->mode() == Variable::CONST) {
-      __ Push(Operand(Factory::the_hole_value()));
+      __ mov(r0, Operand(Factory::the_hole_value()));
+      __ push(r0);
     } else if (node->fun() != NULL) {
       Load(node->fun());
     } else {
-      __ Push(Operand(0));  // no initial value!
+      __ mov(r0, Operand(0));  // no initial value!
+      __ push(r0);
     }
     __ CallRuntime(Runtime::kDeclareContextSlot, 5);
-    // DeclareContextSlot pops the assigned value by accepting an
-    // extra argument and returning the TOS; no need to explicitly pop
-    // here.
+    __ push(r0);
+
     return;
   }
 
@@ -2247,7 +2295,7 @@ void ArmCodeGenerator::VisitDeclaration(Declaration* node) {
     Load(val);
     SetValue(&target);
     // Get rid of the assigned value (declarations are statements).
-    __ pop(r0);  // Pop(no_reg);
+    __ pop();
   }
 }
 
@@ -2258,7 +2306,7 @@ void ArmCodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
   Expression* expression = node->expression();
   expression->MarkAsStatement();
   Load(expression);
-  __ pop(r0);  // __ Pop(no_reg)
+  __ pop();
 }
 
 
@@ -2279,6 +2327,7 @@ void ArmCodeGenerator::VisitIfStatement(IfStatement* node) {
 
   Label exit;
   if (has_then_stm && has_else_stm) {
+    Comment cmnt(masm_, "[ IfThenElse");
     Label then;
     Label else_;
     // if (cond)
@@ -2293,6 +2342,7 @@ void ArmCodeGenerator::VisitIfStatement(IfStatement* node) {
     Visit(node->else_statement());
 
   } else if (has_then_stm) {
+    Comment cmnt(masm_, "[ IfThen");
     ASSERT(!has_else_stm);
     Label then;
     // if (cond)
@@ -2303,6 +2353,7 @@ void ArmCodeGenerator::VisitIfStatement(IfStatement* node) {
     Visit(node->then_statement());
 
   } else if (has_else_stm) {
+    Comment cmnt(masm_, "[ IfElse");
     ASSERT(!has_then_stm);
     Label else_;
     // if (!cond)
@@ -2313,6 +2364,7 @@ void ArmCodeGenerator::VisitIfStatement(IfStatement* node) {
     Visit(node->else_statement());
 
   } else {
+    Comment cmnt(masm_, "[ If");
     ASSERT(!has_then_stm && !has_else_stm);
     // if (cond)
     LoadCondition(node->condition(), CodeGenState::LOAD, &exit, &exit, false);
@@ -2331,8 +2383,7 @@ void ArmCodeGenerator::VisitIfStatement(IfStatement* node) {
 void ArmCodeGenerator::CleanStack(int num_bytes) {
   ASSERT(num_bytes >= 0);
   if (num_bytes > 0) {
-    __ add(sp, sp, Operand(num_bytes - kPointerSize));
-    __ pop(r0);
+    __ add(sp, sp, Operand(num_bytes));
   }
 }
 
@@ -2357,6 +2408,9 @@ void ArmCodeGenerator::VisitReturnStatement(ReturnStatement* node) {
   Comment cmnt(masm_, "[ ReturnStatement");
   if (FLAG_debug_info) RecordStatementPosition(node);
   Load(node->expression());
+  // Move the function result into r0.
+  __ pop(r0);
+
   __ b(&function_return_);
 }
 
@@ -2373,7 +2427,6 @@ void ArmCodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
     __ stop("PushContext: r0 is expected to be the same as cp");
     __ bind(&verified_true);
   }
-  __ pop(r0);  // restore TOS
   // Update context local.
   __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
 }
@@ -2421,11 +2474,13 @@ void ArmCodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
     } else {
       __ bind(&next);
       next.Unuse();
+      __ ldr(r0, MemOperand(sp, 0));
       __ push(r0);  // duplicate TOS
       Load(clause->label());
       Comparison(eq, true);
       Branch(false, &next);
-      __ pop(r0);  // __ Pop(no_reg)
+      // Entering the case statement -> remove the switch value from the stack
+      __ pop(r0);
     }
 
     // Generate code for the body.
@@ -2436,6 +2491,8 @@ void ArmCodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
   }
 
   __ 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);
 
@@ -2532,6 +2589,7 @@ void ArmCodeGenerator::VisitForInStatement(ForInStatement* node) {
 
   // Get the object to enumerate over (converted to JSObject).
   Load(node->enumerable());
+  __ pop(r0);
 
   // Both SpiderMonkey and kjs ignore null and undefined in contrast
   // to the specification.  12.6.4 mandates a call to ToObject.
@@ -2556,7 +2614,8 @@ void ArmCodeGenerator::VisitForInStatement(ForInStatement* node) {
   __ b(hs, &jsobject);
 
   __ bind(&primitive);
-  __ Push(Operand(0));
+  __ push(r0);
+  __ mov(r0, Operand(0));
   __ InvokeBuiltin("TO_OBJECT", 0, CALL_JS);
 
 
@@ -2564,6 +2623,7 @@ void ArmCodeGenerator::VisitForInStatement(ForInStatement* node) {
 
   // Get the set of properties (as a FixedArray or Map).
   __ push(r0);  // duplicate the object being enumerated
+  __ push(r0);
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
 
   // If we got a Map, we can do a fast modification check.
@@ -2580,10 +2640,13 @@ void ArmCodeGenerator::VisitForInStatement(ForInStatement* node) {
   __ ldr(r2,
          FieldMemOperand(r1, DescriptorArray::kEnumCacheBridgeCacheOffset));
 
-  __ Push(Operand(r2));
-  __ Push(FieldMemOperand(r2, FixedArray::kLengthOffset));
+  __ push(r0);  // map
+  __ push(r2);  // enum cache bridge cache
+  __ ldr(r0, FieldMemOperand(r2, FixedArray::kLengthOffset));
   __ mov(r0, Operand(r0, LSL, kSmiTagSize));
-  __ Push(Operand(Smi::FromInt(0)));
+  __ push(r0);
+  __ mov(r0, Operand(Smi::FromInt(0)));
+  __ push(r0);
   __ b(&entry);
 
 
@@ -2591,11 +2654,15 @@ void ArmCodeGenerator::VisitForInStatement(ForInStatement* node) {
 
   __ mov(r1, Operand(Smi::FromInt(0)));
   __ push(r1);  // insert 0 in place of Map
+  __ push(r0);
 
   // Push the length of the array and the initial index onto the stack.
-  __ Push(FieldMemOperand(r0, FixedArray::kLengthOffset));
+  __ ldr(r0, FieldMemOperand(r0, FixedArray::kLengthOffset));
   __ mov(r0, Operand(r0, LSL, kSmiTagSize));
-  __ Push(Operand(Smi::FromInt(0)));
+  __ push(r0);
+  __ mov(r0, Operand(Smi::FromInt(0)));  // init index
+  __ push(r0);
+
   __ b(&entry);
 
   // Body.
@@ -2605,36 +2672,46 @@ void ArmCodeGenerator::VisitForInStatement(ForInStatement* node) {
   // Next.
   __ bind(node->continue_target());
   __ bind(&next);
+  __ pop(r0);
   __ add(r0, r0, Operand(Smi::FromInt(1)));
+  __ push(r0);
 
   // Condition.
   __ bind(&entry);
 
-  __ ldr(ip, MemOperand(sp, 0));
-  __ cmp(r0, Operand(ip));
+  // sp[0] : index
+  // sp[1] : array/enum cache length
+  // sp[2] : array or enum cache
+  // sp[3] : 0 or map
+  // sp[4] : enumerable
+  __ ldr(r0, MemOperand(sp, 0 * kPointerSize));  // load the current count
+  __ ldr(r1, MemOperand(sp, 1 * kPointerSize));  // load the length
+  __ cmp(r0, Operand(r1));  // compare to the array length
   __ b(hs, &cleanup);
 
+  __ ldr(r0, MemOperand(sp, 0 * kPointerSize));
+
   // Get the i'th entry of the array.
-  __ ldr(r2, MemOperand(sp, kPointerSize));
+  __ ldr(r2, MemOperand(sp, 2 * kPointerSize));
   __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   __ ldr(r3, MemOperand(r2, r0, LSL, kPointerSizeLog2 - kSmiTagSize));
 
   // Get Map or 0.
-  __ ldr(r2, MemOperand(sp, 2 * kPointerSize));
+  __ ldr(r2, MemOperand(sp, 3 * kPointerSize));
   // Check if this (still) matches the map of the enumerable.
   // If not, we have to filter the key.
-  __ ldr(r1, MemOperand(sp, 3 * kPointerSize));
+  __ ldr(r1, MemOperand(sp, 4 * kPointerSize));
   __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset));
   __ cmp(r1, Operand(r2));
   __ b(eq, &end_del_check);
 
   // Convert the entry to a string (or null if it isn't a property anymore).
-  __ Push(MemOperand(sp, 4 * kPointerSize));  // push enumerable
-  __ Push(Operand(r3));  // push entry
-  __ Push(Operand(1));
+  __ ldr(r0, MemOperand(sp, 4 * kPointerSize));  // push enumerable
+  __ push(r0);
+  __ push(r3);  // push entry
+  __ mov(r0, Operand(1));
   __ InvokeBuiltin("FILTER_KEY", 1, CALL_JS);
   __ mov(r3, Operand(r0));
-  __ pop(r0);
 
   // If the property has been removed while iterating, we just skip it.
   __ cmp(r3, Operand(Factory::null_value()));
@@ -2644,26 +2721,31 @@ void ArmCodeGenerator::VisitForInStatement(ForInStatement* node) {
   __ bind(&end_del_check);
 
   // Store the entry in the 'each' expression and take another spin in the loop.
-  __ Push(Operand(r3));
+  // r3: i'th entry of the enum cache (or string there of)
+  __ push(r3);  // push entry
   { Reference each(this, node->each());
     if (!each.is_illegal()) {
-      if (each.size() > 0) __ Push(MemOperand(sp, kPointerSize * each.size()));
+      if (each.size() > 0) {
+        __ ldr(r0, MemOperand(sp, kPointerSize * each.size()));
+        __ push(r0);
+      }
       SetValue(&each);
-      if (each.size() > 0) __ pop(r0);
+      if (each.size() > 0) {
+        __ pop(r0);  // discard the value
+      }
     }
   }
-  __ pop(r0);
+  __ pop();  // pop the i'th entry pushed above
   CheckStack();  // TODO(1222600): ignore if body contains calls.
   __ jmp(&loop);
 
   // Cleanup.
   __ bind(&cleanup);
   __ bind(node->break_target());
-  __ add(sp, sp, Operand(4 * kPointerSize));
+  __ add(sp, sp, Operand(5 * kPointerSize));
 
   // Exit.
   __ bind(&exit);
-  __ pop(r0);
 
   break_stack_height_ -= kForInStackSize;
 }
@@ -2674,24 +2756,22 @@ void ArmCodeGenerator::VisitTryCatch(TryCatch* node) {
 
   Label try_block, exit;
 
-  __ push(r0);
   __ bl(&try_block);
 
-
   // --- Catch block ---
 
   // Store the caught exception in the catch variable.
+  __ push(r0);
   { Reference ref(this, node->catch_var());
     // Load the exception to the top of the stack.
-    __ Push(MemOperand(sp, ref.size() * kPointerSize));
+    __ ldr(r0, MemOperand(sp, ref.size() * kPointerSize));
+    __ push(r0);
     SetValue(&ref);
+    __ pop(r0);
   }
 
   // Remove the exception from the stack.
-  __ add(sp, sp, Operand(kPointerSize));
-
-  // Restore TOS register caching.
-  __ pop(r0);
+  __ pop();
 
   VisitStatements(node->catch_block()->statements());
   __ b(&exit);
@@ -2714,6 +2794,7 @@ void ArmCodeGenerator::VisitTryCatch(TryCatch* node) {
 
   // Generate code for the statements in the try block.
   VisitStatements(node->try_block()->statements());
+  __ pop(r0);  // Discard the result.
 
   // Stop the introduced shadowing and count the number of required unlinks.
   int nof_unlinks = 0;
@@ -2732,21 +2813,14 @@ void ArmCodeGenerator::VisitTryCatch(TryCatch* node) {
   ASSERT(StackHandlerConstants::kCodeOffset == 0);  // first field is code
   __ add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize));
   // Code slot popped.
-  __ pop(r0);  // restore TOS
   if (nof_unlinks > 0) __ b(&exit);
 
   // Generate unlink code for all used shadow labels.
   for (int i = 0; i <= nof_escapes; i++) {
     if (shadows[i]->is_linked()) {
-      // Unlink from try chain; be careful not to destroy the TOS.
+      // Unlink from try chain;
       __ bind(shadows[i]);
 
-      bool is_return = (shadows[i]->shadowed() == &function_return_);
-      if (!is_return) {
-        // Break/continue case. TOS is the code slot of the handler.
-        __ push(r0);  // flush TOS
-      }
-
       // Reload sp from the top handler, because some statements that we
       // break from (eg, for...in) may have left stuff on the stack.
       __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
@@ -2758,10 +2832,6 @@ void ArmCodeGenerator::VisitTryCatch(TryCatch* node) {
       __ add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize));
       // Code slot popped.
 
-      if (!is_return) {
-        __ pop(r0);  // restore TOS
-      }
-
       __ b(shadows[i]->shadowed());
     }
   }
@@ -2780,9 +2850,9 @@ void ArmCodeGenerator::VisitTryFinally(TryFinally* node) {
 
   Label exit, unlink, try_block, finally_block;
 
-  __ push(r0);
   __ bl(&try_block);
 
+  __ push(r0);  // save exception object on the stack
   // In case of thrown exceptions, this is where we continue.
   __ mov(r2, Operand(Smi::FromInt(THROWING)));
   __ b(&finally_block);
@@ -2815,7 +2885,8 @@ void ArmCodeGenerator::VisitTryFinally(TryFinally* node) {
   }
 
   // Set the state on the stack to FALLING.
-  __ Push(Operand(Factory::undefined_value()));  // fake TOS
+  __ mov(r0, Operand(Factory::undefined_value()));  // fake TOS
+  __ push(r0);
   __ mov(r2, Operand(Smi::FromInt(FALLING)));
   if (nof_unlinks > 0) __ b(&unlink);
 
@@ -2823,18 +2894,22 @@ void ArmCodeGenerator::VisitTryFinally(TryFinally* node) {
   for (int i = 0; i <= nof_escapes; i++) {
     if (shadows[i]->is_linked()) {
       __ bind(shadows[i]);
-      if (shadows[i]->shadowed() != &function_return_) {
+      if (shadows[i]->shadowed() == &function_return_) {
+        __ push(r0);  // Materialize the return value on the stack
+      } else {
         // Fake TOS for break and continue (not return).
-        __ Push(Operand(Factory::undefined_value()));
+        __ mov(r0, Operand(Factory::undefined_value()));
+        __ push(r0);
       }
       __ mov(r2, Operand(Smi::FromInt(JUMPING + i)));
       __ b(&unlink);
     }
   }
 
-  // Unlink from try chain; be careful not to destroy the TOS.
+  // Unlink from try chain;
   __ bind(&unlink);
 
+  __ pop(r0);  // Store TOS in r0 across stack manipulation
   // Reload sp from the top handler, because some statements that we
   // break from (eg, for...in) may have left stuff on the stack.
   __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
@@ -2846,7 +2921,7 @@ void ArmCodeGenerator::VisitTryFinally(TryFinally* node) {
   ASSERT(StackHandlerConstants::kCodeOffset == 0);  // first field is code
   __ add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize));
   // Code slot popped.
-
+  __ push(r0);
 
   // --- Finally block ---
   __ bind(&finally_block);
@@ -2854,25 +2929,25 @@ void ArmCodeGenerator::VisitTryFinally(TryFinally* node) {
   // Push the state on the stack. If necessary move the state to a
   // local variable to avoid having extra values on the stack while
   // evaluating the finally block.
-  __ Push(Operand(r2));
+  __ push(r2);
   if (node->finally_var() != NULL) {
     Reference target(this, node->finally_var());
     SetValue(&target);
     ASSERT(target.size() == 0);  // no extra stuff on the stack
-    __ pop(r0);
+    __ pop();  // remove the extra avalue that was pushed above
   }
 
   // Generate code for the statements in the finally block.
   VisitStatements(node->finally_block()->statements());
 
-  // Get the state from the stack - or the local variable - and
-  // restore the TOS register.
+  // Get the state from the stack - or the local variable.
   if (node->finally_var() != NULL) {
     Reference target(this, node->finally_var());
     GetValue(&target);
   }
-  __ Pop(r2);
+  __ pop(r2);
 
+  __ pop(r0);  // Restore value or faked TOS.
   // Generate code that jumps to the right destination for all used
   // shadow labels.
   for (int i = 0; i <= nof_escapes; i++) {
@@ -2881,7 +2956,6 @@ void ArmCodeGenerator::VisitTryFinally(TryFinally* node) {
       if (shadows[i]->shadowed() != &function_return_) {
         Label next;
         __ b(ne, &next);
-        __ pop(r0);  // pop faked TOS
         __ b(shadows[i]->shadowed());
         __ bind(&next);
       } else {
@@ -2895,11 +2969,11 @@ void ArmCodeGenerator::VisitTryFinally(TryFinally* node) {
   __ b(ne, &exit);
 
   // Rethrow exception.
+  __ push(r0);
   __ CallRuntime(Runtime::kReThrow, 1);
 
   // Done.
   __ bind(&exit);
-  __ pop(r0);  // restore TOS caching.
 }
 
 
@@ -2907,6 +2981,7 @@ void ArmCodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
   Comment cmnt(masm_, "[ DebuggerStatament");
   if (FLAG_debug_info) RecordStatementPosition(node);
   __ CallRuntime(Runtime::kDebugBreak, 1);
+  __ push(r0);
 }
 
 
@@ -2914,11 +2989,13 @@ void ArmCodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
   ASSERT(boilerplate->IsBoilerplate());
 
   // Push the boilerplate on the stack.
-  __ Push(Operand(boilerplate));
+  __ mov(r0, Operand(boilerplate));
+  __ push(r0);
 
   // Create a new closure.
-  __ Push(Operand(cp));
+  __ push(cp);
   __ CallRuntime(Runtime::kNewClosure, 2);
+  __ push(r0);
 }
 
 
@@ -2961,8 +3038,9 @@ void ArmCodeGenerator::VisitSlot(Slot* node) {
     ASSERT(node->var()->mode() == Variable::DYNAMIC);
 
     // For now, just do a runtime call.
-    __ Push(Operand(cp));
-    __ Push(Operand(node->var()->name()));
+    __ push(cp);
+    __ mov(r0, Operand(node->var()->name()));
+    __ push(r0);
 
     switch (access()) {
       case CodeGenState::UNDEFINED:
@@ -2971,18 +3049,19 @@ void ArmCodeGenerator::VisitSlot(Slot* node) {
 
       case CodeGenState::LOAD:
         __ CallRuntime(Runtime::kLoadContextSlot, 2);
-        // result (TOS) is the value that was loaded
+        __ push(r0);
         break;
 
       case CodeGenState::LOAD_TYPEOF_EXPR:
         __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
-        // result (TOS) is the value that was loaded
+        __ 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;
 
@@ -3004,6 +3083,7 @@ void ArmCodeGenerator::VisitSlot(Slot* node) {
         // need the split into 2 operations: declaration of the
         // context slot followed by initialization.
         __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
+        __ push(r0);
         break;
     }
 
@@ -3020,14 +3100,17 @@ void ArmCodeGenerator::VisitSlot(Slot* node) {
       case CodeGenState::LOAD:  // fall through
       case CodeGenState::LOAD_TYPEOF_EXPR:
         // Special handling for locals allocated in registers.
-        __ Push(SlotOperand(node, r2));
+        __ 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;
 
@@ -3043,6 +3126,7 @@ void ArmCodeGenerator::VisitSlot(Slot* node) {
           __ 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.
@@ -3070,6 +3154,7 @@ void ArmCodeGenerator::VisitSlot(Slot* node) {
         // 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));
         if (node->type() == Slot::CONTEXT) {
           // Skip write barrier if the written value is a smi.
@@ -3082,6 +3167,7 @@ void ArmCodeGenerator::VisitSlot(Slot* node) {
           __ RecordWrite(r2, r3, r1);
           __ bind(&exit);
         }
+        __ push(r0);
         break;
       }
     }
@@ -3117,7 +3203,8 @@ void ArmCodeGenerator::VisitVariableProxy(VariableProxy* proxy_node) {
 
 void ArmCodeGenerator::VisitLiteral(Literal* node) {
   Comment cmnt(masm_, "[ Literal");
-  __ Push(Operand(node->handle()));
+  __ mov(r0, Operand(node->handle()));
+  __ push(r0);
 }
 
 
@@ -3143,16 +3230,19 @@ void ArmCodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
 
   // If the entry is undefined we call the runtime system to computed
   // the literal.
-  __ Push(Operand(r1));                                   // literal array  (0)
-  __ Push(Operand(Smi::FromInt(node->literal_index())));  // literal index  (1)
-  __ Push(Operand(node->pattern()));                      // RegExp pattern (2)
-  __ Push(Operand(node->flags()));                        // RegExp flags   (3)
+  __ push(r1);  // literal array  (0)
+  __ mov(r0, Operand(Smi::FromInt(node->literal_index())));
+  __ push(r0);  // literal index  (1)
+  __ mov(r0, Operand(node->pattern()));  // RegExp pattern (2)
+  __ push(r0);
+  __ mov(r0, Operand(node->flags()));  // RegExp flags   (3)
+  __ push(r0);
   __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
-  __ Pop(r2);
-  __ bind(&done);
+  __ mov(r2, Operand(r0));
 
+  __ bind(&done);
   // Push the literal.
-  __ Push(Operand(r2));
+  __ push(r2);
 }
 
 
@@ -3177,13 +3267,15 @@ void ObjectLiteralDeferred::Generate() {
   // the literal.
 
   // Literal array (0).
-  __ Push(Operand(r1));
+  __ push(r1);
   // Literal index (1).
-  __ Push(Operand(Smi::FromInt(node_->literal_index())));
+  __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
+  __ push(r0);
   // Constant properties (2).
-  __ Push(Operand(node_->constant_properties()));
+  __ mov(r0, Operand(node_->constant_properties()));
+  __ push(r0);
   __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
-  __ Pop(r2);
+  __ mov(r2, Operand(r0));
 }
 
 
@@ -3212,9 +3304,12 @@ void ArmCodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
   __ bind(deferred->exit());
 
   // Push the object literal boilerplate.
-  __ Push(Operand(r2));
+  __ push(r2);
+
   // Clone the boilerplate object.
   __ CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1);
+  __ push(r0);  // save the result
+  // r0: cloned object literal
 
   for (int i = 0; i < node->properties()->length(); i++) {
     ObjectLiteral::Property* property = node->properties()->at(i);
@@ -3224,31 +3319,32 @@ void ArmCodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
       case ObjectLiteral::Property::CONSTANT: break;
       case ObjectLiteral::Property::COMPUTED:  // fall through
       case ObjectLiteral::Property::PROTOTYPE: {
-        // Save a copy of the resulting object on the stack.
-        __ push(r0);
+        __ push(r0);  // dup the result
         Load(key);
         Load(value);
         __ CallRuntime(Runtime::kSetProperty, 3);
-        // Restore the result object from the stack.
-        __ pop(r0);
+        // restore r0
+        __ ldr(r0, MemOperand(sp, 0));
         break;
       }
       case ObjectLiteral::Property::SETTER: {
         __ push(r0);
         Load(key);
-        __ Push(Operand(Smi::FromInt(1)));
+        __ mov(r0, Operand(Smi::FromInt(1)));
+        __ push(r0);
         Load(value);
         __ CallRuntime(Runtime::kDefineAccessor, 4);
-        __ pop(r0);
+        __ ldr(r0, MemOperand(sp, 0));
         break;
       }
       case ObjectLiteral::Property::GETTER: {
         __ push(r0);
         Load(key);
-        __ Push(Operand(Smi::FromInt(0)));
+        __ mov(r0, Operand(Smi::FromInt(0)));
+        __ push(r0);
         Load(value);
         __ CallRuntime(Runtime::kDefineAccessor, 4);
-        __ pop(r0);
+        __ ldr(r0, MemOperand(sp, 0));
         break;
       }
     }
@@ -3268,6 +3364,7 @@ void ArmCodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
     if (value->AsLiteral() == NULL) {
       // The property must be set by generated code.
       Load(value);
+      __ pop(r0);
 
       // Fetch the object literal
       __ ldr(r1, MemOperand(sp, 0));
@@ -3281,8 +3378,6 @@ void ArmCodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
       // Update the write barrier for the array address.
       __ mov(r3, Operand(offset));
       __ RecordWrite(r1, r3, r2);
-
-      __ pop(r0);
     }
   }
 }
@@ -3290,8 +3385,8 @@ void ArmCodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
 
 void ArmCodeGenerator::VisitAssignment(Assignment* node) {
   Comment cmnt(masm_, "[ Assignment");
-
   if (FLAG_debug_info) RecordStatementPosition(node);
+
   Reference target(this, node->target());
   if (target.is_illegal()) return;
 
@@ -3305,9 +3400,12 @@ void ArmCodeGenerator::VisitAssignment(Assignment* node) {
     Literal* literal = node->value()->AsLiteral();
     if (literal != NULL && literal->handle()->IsSmi()) {
       SmiOperation(node->binary_op(), literal->handle(), false);
+      __ push(r0);
+
     } else {
       Load(node->value());
       GenericBinaryOperation(node->binary_op());
+      __ push(r0);
     }
   }
 
@@ -3316,6 +3414,7 @@ void ArmCodeGenerator::VisitAssignment(Assignment* node) {
       (var->mode() == Variable::CONST) &&
       node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
     // Assignment ignored - leave the value on the stack.
+
   } else {
     __ RecordPosition(node->position());
     if (node->op() == Token::INIT_CONST) {
@@ -3336,6 +3435,7 @@ void ArmCodeGenerator::VisitThrow(Throw* node) {
   Load(node->exception());
   __ RecordPosition(node->position());
   __ CallRuntime(Runtime::kThrow, 1);
+  __ push(r0);
 }
 
 
@@ -3344,6 +3444,7 @@ void ArmCodeGenerator::VisitProperty(Property* node) {
   if (is_referenced()) {
     __ RecordPosition(node->position());
     AccessReferenceProperty(node->key(), access());
+
   } else {
     // All stores are through references.
     ASSERT(access() != CodeGenState::STORE);
@@ -3382,22 +3483,21 @@ void ArmCodeGenerator::VisitCall(Call* node) {
     // ----------------------------------
 
     // Push the name of the function and the receiver onto the stack.
-    __ Push(Operand(var->name()));
+    __ mov(r0, Operand(var->name()));
+    __ push(r0);
     LoadGlobal();
 
     // Load the arguments.
     for (int i = 0; i < args->length(); i++) Load(args->at(i));
-    __ Push(Operand(args->length()));
 
     // Setup the receiver register and call the IC initialization code.
     Handle<Code> stub = ComputeCallInitialize(args->length());
-    __ ldr(r1, GlobalObject());
     __ RecordPosition(node->position());
     __ Call(stub, code_target_context);
     __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-
     // Remove the function from the stack.
-    __ add(sp, sp, Operand(kPointerSize));
+    __ pop();
+    __ push(r0);
 
   } else if (var != NULL && var->slot() != NULL &&
              var->slot()->type() == Slot::LOOKUP) {
@@ -3406,17 +3506,19 @@ void ArmCodeGenerator::VisitCall(Call* node) {
     // ----------------------------------
 
     // Load the function
-    __ Push(Operand(cp));
-    __ Push(Operand(var->name()));
+    __ push(cp);
+    __ mov(r0, Operand(var->name()));
+    __ push(r0);
     __ CallRuntime(Runtime::kLoadContextSlot, 2);
     // r0: slot value; r1: receiver
 
     // Load the receiver.
-    __ push(r0);
-    __ mov(r0, Operand(r1));
+    __ push(r0);  // function
+    __ push(r1);  // receiver
 
     // Call the function.
     CallWithArguments(args, node->position());
+    __ push(r0);
 
   } else if (property != NULL) {
     // Check if the key is a literal string.
@@ -3428,22 +3530,23 @@ void ArmCodeGenerator::VisitCall(Call* node) {
       // ------------------------------------------------------------------
 
       // Push the name of the function and the receiver onto the stack.
-      __ Push(Operand(literal->handle()));
+      __ mov(r0, Operand(literal->handle()));
+      __ push(r0);
       Load(property->obj());
 
       // Load the arguments.
       for (int i = 0; i < args->length(); i++) Load(args->at(i));
-      __ Push(Operand(args->length()));
 
       // Set the receiver register and call the IC initialization code.
       Handle<Code> stub = ComputeCallInitialize(args->length());
-      __ ldr(r1, MemOperand(sp, args->length() * kPointerSize));
       __ RecordPosition(node->position());
       __ Call(stub, code_target);
       __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
 
       // Remove the function from the stack.
-      __ add(sp, sp, Operand(kPointerSize));
+      __ pop();
+
+      __ push(r0);  // push after get rid of function from the stack
 
     } else {
       // -------------------------------------------
@@ -3452,13 +3555,14 @@ void ArmCodeGenerator::VisitCall(Call* node) {
 
       // Load the function to call from the property through a reference.
       Reference ref(this, property);
-      GetValue(&ref);
+      GetValue(&ref);  // receiver
 
       // Pass receiver to called function.
-      __ Push(MemOperand(sp, ref.size() * kPointerSize));
-
+      __ ldr(r0, MemOperand(sp, ref.size() * kPointerSize));
+      __ push(r0);
       // Call the function.
       CallWithArguments(args, node->position());
+      __ push(r0);
     }
 
   } else {
@@ -3468,12 +3572,11 @@ void ArmCodeGenerator::VisitCall(Call* node) {
 
     // Load the function.
     Load(function);
-
     // Pass the global object as the receiver.
     LoadGlobal();
-
     // Call the function.
     CallWithArguments(args, node->position());
+    __ push(r0);
   }
 }
 
@@ -3496,34 +3599,39 @@ void ArmCodeGenerator::VisitCallNew(CallNew* node) {
   ZoneList<Expression*>* args = node->arguments();
   for (int i = 0; i < args->length(); i++) Load(args->at(i));
 
-  // Push the number of arguments.
-  __ Push(Operand(args->length()));
+  // r0: the number of arguments.
+  __ mov(r0, Operand(args->length()));
 
   // Call the construct call builtin that handles allocation and
   // constructor invocation.
   __ RecordPosition(position);
   __ Call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)),
           js_construct_call);
-  __ add(sp, sp, Operand(kPointerSize));  // discard
+
+  // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)).
+  __ str(r0, MemOperand(sp, 0 * kPointerSize));
 }
 
 
 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);
-  __ Push(MemOperand(pp, JavaScriptFrameConstants::kFunctionOffset));
+  __ 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));
 }
 
@@ -3531,17 +3639,19 @@ void ArmCodeGenerator::GenerateSetThis(ZoneList<Expression*>* args) {
 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)));
+  __ mov(r0, Operand(Smi::FromInt(0)));  // return a meaningful value
+  __ push(r0);
 }
 
 
 void ArmCodeGenerator::GenerateGetArgumentsLength(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 1);
-  __ push(r0);
   __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kArgsLengthOffset));
   __ mov(r0, Operand(r0, LSL, kSmiTagSize));
+  __ push(r0);
 }
 
 
@@ -3549,19 +3659,20 @@ void ArmCodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 1);
   Label leave;
   Load(args->at(0));
-  // r0 contains object.
-  // if (object->IsSmi()) return TOS.
+  __ pop(r0);  // r0 contains object.
+  // if (object->IsSmi()) return the object.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &leave);
   // It is a heap object - get map.
   __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
   __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));
-  // if (!object->IsJSValue()) return TOS.
+  // if (!object->IsJSValue()) return the object.
   __ cmp(r1, Operand(JS_VALUE_TYPE));
   __ b(ne, &leave);
   // Load the value.
   __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset));
   __ bind(&leave);
+  __ push(r0);
 }
 
 
@@ -3570,9 +3681,8 @@ void ArmCodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
   Label leave;
   Load(args->at(0));  // Load the object.
   Load(args->at(1));  // Load the value.
-  __ pop(r1);
-  // r0 contains value.
-  // r1 contains object.
+  __ pop(r0);  // r0 contains value
+  __ pop(r1);  // r1 contains object
   // if (object->IsSmi()) return object.
   __ tst(r1, Operand(kSmiTagMask));
   __ b(eq, &leave);
@@ -3589,6 +3699,7 @@ void ArmCodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
   __ RecordWrite(r1, r2, r3);
   // Leave.
   __ bind(&leave);
+  __ push(r0);
 }
 
 
@@ -3597,6 +3708,7 @@ void ArmCodeGenerator::GenerateTailCallWithArguments(
   // 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)
@@ -3615,34 +3727,35 @@ void ArmCodeGenerator::GenerateTailCallWithArguments(
 
 void ArmCodeGenerator::GenerateSetArgument(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 3);
-  // r1 = args[i]
+  // r0 = args[i]; r1 = i
   Comment cmnt(masm_, "[ GenerateSetArgument");
-  Load(args->at(1));
-  __ mov(r1, Operand(r0));
-  // r0 = i
-  Load(args->at(0));
+  Load(args->at(1));  // args[i] (value)
+  Load(args->at(0));  // i
+  __ pop(r1);  // i
+  __ pop(r0);  // value
 #if defined(DEBUG)
   { Label L;
-    __ tst(r0, Operand(kSmiTagMask));
+    __ tst(r1, Operand(kSmiTagMask));
     __ b(eq, &L);
     __ stop("SMI expected");
     __ bind(&L);
   }
 #endif  // defined(DEBUG)
   __ add(r2, pp, Operand(JavaScriptFrameConstants::kParam0Offset));
-  __ str(r1,
-         MemOperand(r2, r0, LSL, kPointerSizeLog2 - kSmiTagSize, NegOffset));
-  __ pop(r0);
+  __ str(r0,
+         MemOperand(r2, r1, LSL, kPointerSizeLog2 - kSmiTagSize, NegOffset));
+  __ push(r0);
 }
 
 
 void ArmCodeGenerator::GenerateSquashFrame(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 2);
-  // Load r1 with old number of arguments, r0 with new number, r1 > r0.
-  Load(args->at(0));
-  __ mov(r1, Operand(r0, LSR, kSmiTagSize));
-  Load(args->at(1));
+  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.
@@ -3663,17 +3776,20 @@ void ArmCodeGenerator::GenerateSquashFrame(ZoneList<Expression*>* args) {
 
   // Move down stack pointer esp.
   __ mov(sp, Operand(r1));
-  // Balance stack and put something GC-able in r0.
-  __ pop(r0);
+  // 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 r1 with new number of arguments, r0 with old number (as Smi), r1 > r0.
   Load(args->at(1));
-  __ mov(r1, Operand(r0, LSR, kSmiTagSize));
   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;
@@ -3684,7 +3800,6 @@ void ArmCodeGenerator::GenerateExpandFrame(ZoneList<Expression*>* args) {
     __ ldr(ip, MemOperand(ip));
     __ cmp(r2, Operand(ip));
     __ b(gt, &not_too_big);
-    __ pop(r0);
     __ mov(r0, Operand(Factory::false_value()));
     __ b(&end_of_expand_frame);
     __ bind(&not_too_big);
@@ -3710,18 +3825,18 @@ void ArmCodeGenerator::GenerateExpandFrame(ZoneList<Expression*>* args) {
   __ cmp(r3, Operand(r0));
   __ b(ne, &move);
 
-  // Balance stack and put success value in top of stack
-  __ pop(r0);
+  // 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));
-  __ tst(r0, Operand(kSmiTagMask));
   __ pop(r0);
+  __ tst(r0, Operand(kSmiTagMask));
   cc_reg_ = eq;
 }
 
@@ -3731,8 +3846,8 @@ void ArmCodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
 // It is not yet implemented on ARM, so it always goes to the slow case.
 void ArmCodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 2);
-  __ push(r0);
   __ mov(r0, Operand(Factory::undefined_value()));
+  __ push(r0);
 }
 
 
@@ -3748,15 +3863,14 @@ void ArmCodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
 void ArmCodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
   ASSERT(args->length() == 0);
 
-  // Flush the TOS cache and seed the result with the formal
-  // parameters count, which will be used in case no arguments adaptor
-  // frame is found below the current frame.
-  __ push(r0);
+  // Seed the result with the formal parameters count, which will be used
+  // in case no arguments adaptor frame is found below the current frame.
   __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters())));
 
   // Call the shared stub to get to the arguments.length.
   ArgumentsAccessStub stub(true);
   __ CallStub(&stub);
+  __ push(r0);
 }
 
 
@@ -3766,48 +3880,52 @@ void ArmCodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) {
   // Load the key onto the stack and set register r1 to the formal
   // parameters count for the currently executing function.
   Load(args->at(0));
+  __ pop(r0);
   __ mov(r1, Operand(Smi::FromInt(scope_->num_parameters())));
 
   // Call the shared stub to get to arguments[key].
   ArgumentsAccessStub stub(false);
   __ CallStub(&stub);
+  __ push(r0);
 }
 
 
 void ArmCodeGenerator::GenerateShiftDownAndTailCall(
     ZoneList<Expression*>* args) {
-    // r0 = number of arguments
-    ASSERT(args->length() == 1);
-    Load(args->at(0));
-    __ 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)
-    __ add(sp, sp, Operand(kPointerSize));
-
-    // 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;
+  // 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;
 }
 
 
@@ -3819,28 +3937,31 @@ void ArmCodeGenerator::VisitCallRuntime(CallRuntime* node) {
   Comment cmnt(masm_, "[ CallRuntime");
   Runtime::Function* function = node->function();
 
-  if (function == NULL) {
+  if (function != NULL) {
+    // Push the arguments ("left-to-right").
+    for (int i = 0; i < args->length(); i++) Load(args->at(i));
+
+    // Call the C runtime function.
+    __ CallRuntime(function, args->length());
+    __ push(r0);
+
+  } else {
     // Prepare stack for calling JS runtime function.
-    __ Push(Operand(node->name()));
+    __ mov(r0, Operand(node->name()));
+    __ push(r0);
     // Push the builtins object found in the current global object.
     __ ldr(r1, GlobalObject());
-    __ Push(FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
-  }
+    __ ldr(r0, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
+    __ push(r0);
 
-  // Push the arguments ("left-to-right").
-  for (int i = 0; i < args->length(); i++) Load(args->at(i));
+    for (int i = 0; i < args->length(); i++) Load(args->at(i));
 
-  if (function != NULL) {
-    // Call the C runtime function.
-    __ CallRuntime(function, args->length());
-  } else {
     // Call the JS runtime function.
-    __ Push(Operand(args->length()));
-    __ ldr(r1, MemOperand(sp, args->length() * kPointerSize));
     Handle<Code> stub = ComputeCallInitialize(args->length());
     __ Call(stub, code_target);
     __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-    __ add(sp, sp, Operand(kPointerSize));
+    __ pop();
+    __ push(r0);
   }
 }
 
@@ -3860,54 +3981,59 @@ void ArmCodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
 
   } else if (op == Token::DELETE) {
     Property* property = node->expression()->AsProperty();
+    Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
     if (property != NULL) {
       Load(property->obj());
       Load(property->key());
-      __ Push(Operand(1));  // not counting receiver
+      __ mov(r0, Operand(1));  // not counting receiver
       __ InvokeBuiltin("DELETE", 1, CALL_JS);
-      return;
-    }
 
-    Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
-    if (variable != NULL) {
+    } else if (variable != NULL) {
       Slot* slot = variable->slot();
       if (variable->is_global()) {
         LoadGlobal();
-        __ Push(Operand(variable->name()));
-        __ Push(Operand(1));  // not counting receiver
+        __ mov(r0, Operand(variable->name()));
+        __ push(r0);
+        __ mov(r0, Operand(1));  // not counting receiver
         __ InvokeBuiltin("DELETE", 1, CALL_JS);
-        return;
 
       } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
         // lookup the context holding the named variable
-        __ Push(Operand(cp));
-        __ Push(Operand(variable->name()));
+        __ push(cp);
+        __ mov(r0, Operand(variable->name()));
+        __ push(r0);
         __ CallRuntime(Runtime::kLookupContext, 2);
         // r0: context
-        __ Push(Operand(variable->name()));
-        __ Push(Operand(1));  // not counting receiver
+        __ push(r0);
+        __ mov(r0, Operand(variable->name()));
+        __ push(r0);
+        __ mov(r0, Operand(1));  // not counting receiver
         __ InvokeBuiltin("DELETE", 1, CALL_JS);
-        return;
-      }
 
-      // Default: Result of deleting non-global, not dynamically
-      // introduced variables is false.
-      __ Push(Operand(Factory::false_value()));
+      } else {
+        // Default: Result of deleting non-global, not dynamically
+        // introduced variables is false.
+        __ mov(r0, Operand(Factory::false_value()));
+      }
 
     } else {
       // Default: Result of deleting expressions is true.
       Load(node->expression());  // may have side-effects
+      __ pop();
       __ mov(r0, Operand(Factory::true_value()));
     }
+    __ push(r0);
 
   } else if (op == Token::TYPEOF) {
     // Special case for loading the typeof expression; see comment on
     // LoadTypeofExpression().
     LoadTypeofExpression(node->expression());
     __ CallRuntime(Runtime::kTypeof, 1);
+    __ push(r0);  // r0 has result
 
   } else {
     Load(node->expression());
+    __ pop(r0);
     switch (op) {
       case Token::NOT:
       case Token::DELETE:
@@ -3928,7 +4054,8 @@ void ArmCodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
         __ tst(r0, Operand(kSmiTagMask));
         __ b(eq, &smi_label);
 
-        __ Push(Operand(0));  // not counting receiver
+        __ push(r0);
+        __ mov(r0, Operand(0));  // not counting receiver
         __ InvokeBuiltin("BIT_NOT", 0, CALL_JS);
 
         __ b(&continue_label);
@@ -3946,13 +4073,15 @@ void ArmCodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
         break;
 
       case Token::ADD:
-        __ Push(Operand(0));  // not counting receiver
+        __ push(r0);
+        __ mov(r0, Operand(0));  // not counting receiver
         __ InvokeBuiltin("TO_NUMBER", 0, CALL_JS);
         break;
 
       default:
         UNREACHABLE();
     }
+    __ push(r0);  // r0 has result
   }
 }
 
@@ -3967,11 +4096,15 @@ void ArmCodeGenerator::VisitCountOperation(CountOperation* node) {
   bool is_const = (var != NULL && var->mode() == Variable::CONST);
 
   // Postfix: Make room for the result.
-  if (is_postfix) __ Push(Operand(0));
+  if (is_postfix) {
+     __ mov(r0, Operand(0));
+     __ push(r0);
+  }
 
   { Reference target(this, node->expression());
     if (target.is_illegal()) return;
     GetValue(&target);
+    __ pop(r0);
 
     Label slow, exit;
 
@@ -4024,6 +4157,7 @@ void ArmCodeGenerator::VisitCountOperation(CountOperation* node) {
 
     // Store the new value in the target if not const.
     __ bind(&exit);
+    __ push(r0);
     if (!is_const) SetValue(&target);
   }
 
@@ -4069,10 +4203,12 @@ void ArmCodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
     } else {
       Label pop_and_continue, exit;
 
+      __ ldr(r0, MemOperand(sp, 0));  // dup the stack top
+      __ push(r0);
       // Avoid popping the result if it converts to 'false' using the
       // standard ToBoolean() conversion as described in ECMA-262,
       // section 9.2, page 30.
-      ToBoolean(r0, &pop_and_continue, &exit);
+      ToBoolean(&pop_and_continue, &exit);
       Branch(false, &exit);
 
       // Pop the result of evaluating the first part.
@@ -4108,10 +4244,12 @@ void ArmCodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
     } else {
       Label pop_and_continue, exit;
 
+      __ ldr(r0, MemOperand(sp, 0));
+      __ push(r0);
       // Avoid popping the result if it converts to 'true' using the
       // standard ToBoolean() conversion as described in ECMA-262,
       // section 9.2, page 30.
-      ToBoolean(r0, &exit, &pop_and_continue);
+      ToBoolean(&exit, &pop_and_continue);
       Branch(true, &exit);
 
       // Pop the result of evaluating the first part.
@@ -4145,12 +4283,14 @@ void ArmCodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
       Load(node->right());
       GenericBinaryOperation(node->op());
     }
+    __ push(r0);
   }
 }
 
 
 void ArmCodeGenerator::VisitThisFunction(ThisFunction* node) {
-  __ Push(FunctionOperand());
+  __ ldr(r0, FunctionOperand());
+  __ push(r0);
 }
 
 
@@ -4177,6 +4317,7 @@ void ArmCodeGenerator::VisitCompareOperation(CompareOperation* node) {
     if (left_is_null || right_is_null) {
       Load(left_is_null ? right : left);
       Label exit, undetectable;
+      __ pop(r0);
       __ cmp(r0, Operand(Factory::null_value()));
 
       // The 'null' value is only equal to 'undefined' if using
@@ -4190,7 +4331,6 @@ void ArmCodeGenerator::VisitCompareOperation(CompareOperation* node) {
         __ tst(r0, Operand(kSmiTagMask));
 
         __ b(ne, &undetectable);
-        __ pop(r0);
         __ b(false_target());
 
         __ bind(&undetectable);
@@ -4201,7 +4341,6 @@ void ArmCodeGenerator::VisitCompareOperation(CompareOperation* node) {
       }
 
       __ bind(&exit);
-      __ pop(r0);
 
       cc_reg_ = eq;
       return;
@@ -4220,10 +4359,9 @@ void ArmCodeGenerator::VisitCompareOperation(CompareOperation* node) {
        right->AsLiteral()->handle()->IsString())) {
     Handle<String> check(String::cast(*right->AsLiteral()->handle()));
 
-    // Load the operand, move it to register r1, and restore TOS.
+    // Load the operand, move it to register r1.
     LoadTypeofExpression(operation->expression());
-    __ mov(r1, Operand(r0));
-    __ pop(r0);
+    __ pop(r1);
 
     if (check->Equals(Heap::number_symbol())) {
       __ tst(r1, Operand(kSmiTagMask));
@@ -4333,13 +4471,15 @@ void ArmCodeGenerator::VisitCompareOperation(CompareOperation* node) {
       break;
 
     case Token::IN:
-      __ Push(Operand(1));  // not counting receiver
+      __ mov(r0, Operand(1));  // not counting receiver
       __ InvokeBuiltin("IN", 1, CALL_JS);
+      __ push(r0);
       break;
 
     case Token::INSTANCEOF:
-      __ Push(Operand(1));  // not counting receiver
+      __ mov(r0, Operand(1));  // not counting receiver
       __ InvokeBuiltin("INSTANCE_OF", 1, CALL_JS);
+      __ push(r0);
       break;
 
     default:
index e240a137ee5381a96727f54a3a2e1f5de51d7447..bec5ab474e92ccf4e15468ee94daa301b5ccae0b 100644 (file)
@@ -42,11 +42,14 @@ 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_code, false, "print generated code");
 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,
@@ -322,10 +325,13 @@ class Ia32CodeGenerator: public CodeGenerator {
 Handle<Code> Ia32CodeGenerator::MakeCode(FunctionLiteral* flit,
                                          Handle<Script> script,
                                          bool is_eval) {
+#ifdef ENABLE_DISASSEMBLER
+  bool print_code = FLAG_print_code && !Bootstrapper::IsActive();
+#endif
+
 #ifdef DEBUG
   bool print_source = false;
   bool print_ast = false;
-  bool print_code = false;
   const char* ftype;
 
   if (Bootstrapper::IsActive()) {
@@ -336,7 +342,6 @@ Handle<Code> Ia32CodeGenerator::MakeCode(FunctionLiteral* flit,
   } else {
     print_source = FLAG_print_source;
     print_ast = FLAG_print_ast;
-    print_code = FLAG_print_code;
     ftype = "user-defined";
   }
 
@@ -377,7 +382,7 @@ Handle<Code> Ia32CodeGenerator::MakeCode(FunctionLiteral* flit,
   // Add unresolved entries in the code to the fixup list.
   Bootstrapper::AddFixup(*code, cgen.masm());
 
-#ifdef DEBUG
+#ifdef ENABLE_DISASSEMBLER
   if (print_code) {
     // Print the source code if available.
     if (!script->IsUndefined() && !script->source()->IsUndefined()) {
@@ -393,9 +398,9 @@ Handle<Code> Ia32CodeGenerator::MakeCode(FunctionLiteral* flit,
       PrintF("\n\n");
     }
     PrintF("--- Code ---\n");
-    code->Print();
+    code->Disassemble();
   }
-#endif  // DEBUG
+#endif  // ENABLE_DISASSEMBLER
 
   return code;
 }
@@ -1710,8 +1715,7 @@ void ArgumentsAccessStub::Generate(MacroAssembler* masm) {
   // by calling the runtime system.
   if (!is_length_) {
     __ bind(&slow);
-    __ Set(eax, Immediate(0));  // not counting receiver
-    __ JumpToBuiltin(ExternalReference(Runtime::kGetArgumentsProperty));
+    __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
   }
 }
 
@@ -2268,8 +2272,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
   __ push(eax);
 
   // Do tail-call to runtime routine.
-  __ Set(eax, Immediate(0));  // not counting receiver
-  __ JumpToBuiltin(ExternalReference(Runtime::kStackGuard));
+  __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
 }
 
 
@@ -5020,7 +5023,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
   // ebx: pointer to C function  (C callee-saved)
   // ebp: frame pointer  (restored after C call)
   // esp: stack pointer  (restored after C call)
-  // edi: number of arguments  (C callee-saved)
+  // edi: number of arguments including receiver  (C callee-saved)
 
   if (do_gc) {
     __ mov(Operand(esp, 0 * kPointerSize), eax);  // Result.
@@ -5028,8 +5031,10 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
   }
 
   // Call C function.
-  __ lea(eax,
-         Operand(ebp, edi, times_4, StandardFrameConstants::kCallerSPOffset));
+  __ lea(eax, Operand(ebp,
+                      edi,
+                      times_4,
+                      StandardFrameConstants::kCallerSPOffset - kPointerSize));
   __ mov(Operand(esp, 0 * kPointerSize), edi);  // argc.
   __ mov(Operand(esp, 1 * kPointerSize), eax);  // argv.
   __ call(Operand(ebx));
@@ -5073,7 +5078,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
 
   // Pop arguments from caller's stack and return.
   __ pop(ebx);  // Ok to clobber ebx - function pointer not needed anymore.
-  __ lea(esp, Operand(esp, ecx, times_4, +1 * kPointerSize));  // +1 ~ receiver.
+  __ lea(esp, Operand(esp, ecx, times_4, 0));
   __ push(ebx);
   __ ret(0);
 
@@ -5162,7 +5167,7 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {
 
 
 void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
-  // eax: number of arguments
+  // eax: number of arguments including receiver
   // ebx: pointer to C function  (C callee-saved)
   // ebp: frame pointer  (restored after C call)
   // esp: stack pointer  (restored after C call)
@@ -5219,7 +5224,7 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
   // ebx: pointer to builtin function  (C callee-saved)
   // ebp: frame pointer  (restored after C call)
   // esp: stack pointer  (restored after C call)
-  // edi: number of arguments  (C callee-saved)
+  // edi: number of arguments including receiver (C callee-saved)
 
   Label entry;
   __ bind(&entry);
index c140c37ed00f1826feda70eec14ed8869b2d9f5c..fc057a961bf3b34aab18a4ed9927e25bffcd7e6e 100644 (file)
@@ -276,7 +276,7 @@ const char* RuntimeStub::GetName() {
 
 
 void RuntimeStub::Generate(MacroAssembler* masm) {
-  masm->TailCallRuntime(Runtime::FunctionForId((Runtime::FunctionId)id_));
+  masm->TailCallRuntime(ExternalReference(id_), num_arguments_);
 }
 
 
index e2f069f9a91c0d4b4693f1cf56a27be3675b532d..4782753b24ab0928654c26bfdeca9e71966e68c8 100644 (file)
@@ -182,15 +182,28 @@ class CodeGenerator: public Visitor {
 // RuntimeStub models code stubs calling entrypoints in the Runtime class.
 class RuntimeStub : public CodeStub {
  public:
-  explicit RuntimeStub(Runtime::FunctionId id) : id_(id) { }
+  explicit RuntimeStub(Runtime::FunctionId id, int num_arguments)
+      : id_(id), num_arguments_(num_arguments) { }
 
   void Generate(MacroAssembler* masm);
 
+  // Disassembler support.  It is useful to be able to print the name
+  // of the runtime function called through this stub.
+  static const char* GetNameFromMinorKey(int minor_key) {
+    return Runtime::FunctionForId(IdField::decode(minor_key))->stub_name;
+  }
+
  private:
   Runtime::FunctionId id_;
+  int num_arguments_;
+
+  class ArgumentField: public BitField<int,  0, 16> {};
+  class IdField: public BitField<Runtime::FunctionId, 16, kMinorBits - 16> {};
 
   Major MajorKey() { return Runtime; }
-  int MinorKey() { return id_; }
+  int MinorKey() {
+    return IdField::encode(id_) | ArgumentField::encode(num_arguments_);
+  }
 
   const char* GetName();
 
index 9a1dc319382e312f612c42e854dc5fbae1da8783..4faa967363adddd572e0ebe95eb1fd9c21af97b0 100644 (file)
@@ -134,7 +134,7 @@ var local_time_offset;
 
 function LocalTimeOffset() {
   if (IS_UNDEFINED(local_time_offset)) {
-    local_time_offset = %DateLocalTimeOffset(0);
+    local_time_offset = %DateLocalTimeOffset();
   }
   return local_time_offset;
 };
@@ -355,11 +355,11 @@ function TimeClip(time) {
 
 
 %SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
-  if (%IsConstructCall(this)) {
+  if (%IsConstructCall()) {
     // ECMA 262 - 15.9.3
     var argc = %_ArgumentsLength();
     if (argc == 0) {
-      %_SetValueOf(this, %DateCurrentTime(argc));
+      %_SetValueOf(this, %DateCurrentTime());
       return;
     }
     if (argc == 1) {
@@ -585,7 +585,7 @@ function DateUTC(year, month, date, hours, minutes, seconds, ms) {
 // Mozilla-specific extension. Returns the number of milliseconds
 // elapsed since 1 January 1970 00:00:00 UTC.
 function DateNow() {
-  return %DateCurrentTime(0);
+  return %DateCurrentTime();
 };
 
 
index dae097d9e21d5a168397a859f882d91c52abdb2d..1409f783e4265dc5837935cdb8fee7fb34408e97 100644 (file)
@@ -395,7 +395,7 @@ Debug.removeListener = function(listener) {
 };
 
 Debug.Break = function(f) {
-  %Break(0);
+  %Break();
 };
 
 Debug.breakLocations = function(f) {
@@ -622,7 +622,7 @@ Debug.scriptBreakPoints = function() {
 
 
 Debug.clearStepping = function() {
-  %ClearStepping(0);
+  %ClearStepping();
 }
 
 Debug.setBreakOnException = function() {
@@ -667,7 +667,7 @@ Debug.showBreakPoints = function(f, full) {
 // scanning the heap.
 Debug.scripts = function() {
   // Collect all scripts in the heap.
-  return %DebugGetLoadedScripts(0);
+  return %DebugGetLoadedScripts();
 }
 
 function MakeExecutionState(break_id) {
@@ -1858,7 +1858,7 @@ DebugCommandProcessor.prototype.scriptsRequest_ = function(request, response) {
   }
 
   // Collect all scripts in the heap.
-  var scripts = %DebugGetLoadedScripts(0);
+  var scripts = %DebugGetLoadedScripts();
 
   response.body = [];
 
@@ -1896,7 +1896,7 @@ DebugCommandProcessor.prototype.isRunning = function(json_response) {
 
 
 DebugCommandProcessor.prototype.systemBreak = function(cmd, args) {
-  return %SystemBreak(0);
+  return %SystemBreak();
 };
 
 
index 7901ca1e3c79153d2771572b88f71d5aa168ed60..4baad88b6330d4c687ad526b29d66584ac7aff1c 100644 (file)
@@ -618,7 +618,7 @@ void Debug::Iterate(ObjectVisitor* v) {
 
 Object* Debug::Break(Arguments args) {
   HandleScope scope;
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 0);
 
   // Get the top-most JavaScript frame.
   JavaScriptFrameIterator it;
@@ -627,7 +627,7 @@ Object* Debug::Break(Arguments args) {
   // Just continue if breaks are disabled or debugger cannot be loaded.
   if (disable_break() || !Load()) {
     SetAfterBreakTarget(frame);
-    return args[0];
+    return Heap::undefined_value();
   }
 
   SaveBreakFrame save;
@@ -689,7 +689,7 @@ Object* Debug::Break(Arguments args) {
   // Install jump to the call address which was overwritten.
   SetAfterBreakTarget(frame);
 
-  return args[0];
+  return Heap::undefined_value();
 }
 
 
index dba4a3dc58d084627b3e8bf33c902a9672270fdf..51a9bf12ae2c93767b6877adc4f3de1b2569dbb7 100644 (file)
@@ -28,6 +28,7 @@
 #include "v8.h"
 
 #include "code-stubs.h"
+#include "codegen.h"
 #include "debug.h"
 #include "disasm.h"
 #include "disassembler.h"
@@ -234,9 +235,9 @@ static int DecodeIt(FILE* f,
                   out.AddFormatted("argc = %d)", minor_key);
                   break;
                 case CodeStub::Runtime: {
-                  Runtime::FunctionId id =
-                      static_cast<Runtime::FunctionId>(minor_key);
-                  out.AddFormatted("%s)", Runtime::FunctionForId(id)->name);
+                  const char* name =
+                      RuntimeStub::GetNameFromMinorKey(minor_key);
+                  out.AddFormatted("%s)", name);
                   break;
                 }
                 default:
index 1fcaf0b7684a5779f48c4b0a49c541de2c87354e..ba7dc3ccba639f9e4a97eb3304e9a93ad91f27fb 100644 (file)
@@ -664,13 +664,6 @@ Handle<JSFunction> Factory::CreateApiFunction(
     map->set_needs_access_check();
   }
 
-  // If the function template info specifies a lookup handler the
-  // initial_map must have set the bit has_special_lookup.
-  if (obj->lookup_callback()->IsProxy()) {
-    ASSERT(!map->has_special_lookup());
-    map->set_special_lookup();
-  }
-
   // Set interceptor information in the map.
   if (!obj->named_property_handler()->IsUndefined()) {
     map->set_has_named_interceptor();
index 319b5670069a72b760e4451294a72040f4a2de31..e08758f2b0877b57fc276f876202da1125abc490 100644 (file)
@@ -68,7 +68,7 @@ static const RegList kCalleeSaved =
   kR9Available
     <<  9 |  //  r9 v6
   1 << 10 |  // r10 v7 (pp in JavaScript code)
-  1 << 11 ;  // r11 v8 (fp in JavaScript code)
+  1 << 11  // r11 v8 (fp in JavaScript code)
 
 static const int kNumCalleeSaved = 7 + kR9Available;
 
index cfc012e44caae0e80a7849c68e3e6c6e5ffd7722..2b9551c6463611a32cfc048932dab8e9f318453f 100644 (file)
@@ -81,13 +81,13 @@ class StackHandler BASE_EMBEDDED {
   static const int kCodeNotPresent = 0;
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
-
   // Accessors.
   inline State state() const;
 
   inline Address pc() const;
   inline void set_pc(Address value);
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
 };
 
 
@@ -187,9 +187,6 @@ class StackFrame BASE_EMBEDDED {
   // Compute the stack frame type for the given state.
   static Type ComputeType(State* state);
 
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(StackFrame);
-
  protected:
   // TODO(1233523): Once the ARM code uses the new calling
   // conventions, we should be able to make state_ private again.
@@ -207,6 +204,8 @@ class StackFrame BASE_EMBEDDED {
 
   friend class StackFrameIterator;
   friend class StackHandlerIterator;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StackFrame);
 };
 
 
index ebce468947b888c9cf0ed40be0668d0ba45065d4..cd2fb2a5fbc45ed64a051e30f39fe4f84e5faf51 100644 (file)
@@ -985,11 +985,17 @@ class MarkingStack {
 
   void clear_overflowed() { overflowed_ = false; }
 
+  // Push the (marked) object on the marking stack if there is room,
+  // otherwise mark the object as overflowed and wait for a rescan of the
+  // heap.
   void Push(HeapObject* object) {
-    ASSERT(!is_full());
     CHECK(object->IsHeapObject());
-    *(top_++) = object;
-    if (is_full()) overflowed_ = true;
+    if (is_full()) {
+      object->SetOverflow();
+      overflowed_ = true;
+    } else {
+      *(top_++) = object;
+    }
   }
 
   HeapObject* Pop() {
index d39808e86888e0a5d35fcf502c367b2bfcd1ccb9..869ffcbc896db5de37da9ec4996a059f583a9b17 100644 (file)
@@ -125,7 +125,6 @@ static void GenerateDictionaryLoad(MacroAssembler* masm,
 
 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
@@ -133,6 +132,8 @@ void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
 
   Label miss;
 
+  __ ldr(r0, MemOperand(sp, 0));
+
   // Check that the receiver isn't a smi.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &miss);
@@ -156,7 +157,6 @@ void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
 
 void LoadIC::GenerateShortStringLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
@@ -164,6 +164,8 @@ void LoadIC::GenerateShortStringLength(MacroAssembler* masm) {
 
   Label miss;
 
+  __ ldr(r0, MemOperand(sp, 0));
+
   // Check that the receiver isn't a smi.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &miss);
@@ -191,7 +193,6 @@ void LoadIC::GenerateShortStringLength(MacroAssembler* masm) {
 
 void LoadIC::GenerateMediumStringLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
@@ -199,6 +200,8 @@ void LoadIC::GenerateMediumStringLength(MacroAssembler* masm) {
 
   Label miss;
 
+  __ ldr(r0, MemOperand(sp, 0));
+
   // Check that the receiver isn't a smi.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &miss);
@@ -225,7 +228,6 @@ void LoadIC::GenerateMediumStringLength(MacroAssembler* masm) {
 
 void LoadIC::GenerateLongStringLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
@@ -233,6 +235,7 @@ void LoadIC::GenerateLongStringLength(MacroAssembler* masm) {
 
   Label miss;
 
+  __ ldr(r0, MemOperand(sp, 0));
   // Check that the receiver isn't a smi.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &miss);
@@ -259,7 +262,6 @@ void LoadIC::GenerateLongStringLength(MacroAssembler* masm) {
 
 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
@@ -278,15 +280,14 @@ Object* CallIC_Miss(Arguments args);
 
 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
   // ----------- S t a t e -------------
-  //  -- r0: number of arguments
-  //  -- r1: receiver
   //  -- lr: return address
   // -----------------------------------
   Label number, non_number, non_string, boolean, probe, miss;
 
+  // Get the receiver of the function from the stack into r1.
+  __ ldr(r1, MemOperand(sp, argc * kPointerSize));
   // Get the name of the function from the stack; 1 ~ receiver.
-  __ add(ip, sp, Operand(r0, LSL, kPointerSizeLog2));
-  __ ldr(r2, MemOperand(ip, 1 * kPointerSize));
+  __ ldr(r2, MemOperand(sp, (argc + 1) * kPointerSize));
 
   // Probe the stub cache.
   Code::Flags flags =
@@ -340,12 +341,13 @@ void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
 
 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
   // ----------- S t a t e -------------
-  //  -- r1: receiver
   //  -- lr: return address
   // -----------------------------------
 
   Label miss, probe, done, global;
 
+  // Get the receiver of the function from the stack into r1.
+  __ ldr(r1, MemOperand(sp, argc * kPointerSize));
   // Get the name of the function from the stack; 1 ~ receiver.
   __ ldr(r2, MemOperand(sp, (argc + 1) * kPointerSize));
 
@@ -405,11 +407,12 @@ void CallIC::Generate(MacroAssembler* masm,
   //  -- 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));
-
-  __ mov(r0, Operand(argc));  // Setup number of arguments for EnterJSFrame.
   __ EnterJSFrame(0);
+  __ pop();  // remove the code slot
 
   // Push the receiver and the name of the function.
   __ ldr(r0, MemOperand(pp, 0));
@@ -417,7 +420,7 @@ void CallIC::Generate(MacroAssembler* masm,
   __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit());
 
   // Call the entry.
-  __ mov(r0, Operand(2 - 1));  // do not count receiver
+  __ mov(r0, Operand(2));
   __ mov(r1, Operand(f));
 
   CEntryStub stub;
@@ -442,12 +445,12 @@ Object* LoadIC_Miss(Arguments args);
 
 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
   // -----------------------------------
 
+  __ ldr(r0, MemOperand(sp, 0));
   // Probe the stub cache.
   Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC);
   StubCache::GenerateProbe(masm, flags, r0, r2, r3);
@@ -459,7 +462,6 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
 
 void LoadIC::GenerateNormal(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
@@ -467,6 +469,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
 
   Label miss, probe, done, global;
 
+  __ ldr(r0, MemOperand(sp, 0));
   // Check that the receiver isn't a smi.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &miss);
@@ -495,7 +498,6 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
 
   // Cache miss: Restore receiver from stack and jump to runtime.
   __ bind(&miss);
-  __ ldr(r0, MemOperand(sp));
   Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
 }
 
@@ -507,18 +509,17 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
 
 void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
   // -----------------------------------
 
+  __ ldr(r0, MemOperand(sp, 0));
   __ push(r0);
   __ push(r2);
 
-  // Set the number of arguments and jump to the entry.
-  __ mov(r0, Operand(2 - 1));  // not counting receiver.
-  __ JumpToBuiltin(f);
+  // Perform tail call to the entry.
+  __ TailCallRuntime(f, 2);
 }
 
 
@@ -572,9 +573,8 @@ void StoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ ldr(r3, MemOperand(sp));  // copy receiver
   __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
 
-  // Set the number of arguments and jump to the entry.
-  __ mov(r0, Operand(3 - 1));  // not counting receiver.
-  __ JumpToBuiltin(f);
+  // Perform tail call to the entry.
+  __ TailCallRuntime(f, 3);
 }
 
 
index 38216b5bfc1cd7b071638fb8fc68fe0114f63d46..e7f89d5185cf42d46add5b05a28b7d3a581e7a16 100644 (file)
@@ -248,8 +248,6 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   __ j(below, &fast, taken);
   // Slow case: Load name and receiver from stack and jump to runtime.
   __ bind(&slow);
-  __ mov(eax, Operand(esp, 1 * kPointerSize));  // 1 ~ return address.
-  __ mov(ecx, Operand(esp, 2 * kPointerSize));  // 1 ~ return address, name.
   __ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
   KeyedLoadIC::Generate(masm, ExternalReference(Runtime::kGetProperty));
   // Check if the key is a symbol that is not an array index.
@@ -333,8 +331,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
   __ push(eax);
   __ push(ecx);
   // Do tail-call to runtime routine.
-  __ Set(eax, Immediate(2));  // not counting receiver
-  __ JumpToBuiltin(ExternalReference(Runtime::kSetProperty));
+  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
 
 
   // Extra capacity case: Check if there is extra capacity to
@@ -530,7 +527,7 @@ void CallIC::Generate(MacroAssembler* masm,
 
   // Call the entry.
   CEntryStub stub;
-  __ mov(Operand(eax), Immediate(2 - 1));  // do not count receiver
+  __ mov(Operand(eax), Immediate(2));
   __ mov(Operand(ebx), Immediate(f));
   __ CallStub(&stub);
 
@@ -636,9 +633,8 @@ void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ push(ecx);
   __ push(ebx);
 
-  // Set the number of arguments and jump to the entry.
-  __ mov(Operand(eax), Immediate(1));  // not counting receiver.
-  __ JumpToBuiltin(f);
+  // Perform tail call to the entry.
+  __ TailCallRuntime(f, 2);
 }
 
 
@@ -673,9 +669,8 @@ void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ push(eax);
   __ push(ebx);
 
-  // Set the number of arguments and jump to the entry.
-  __ mov(Operand(eax), Immediate(1));  // not counting receiver.
-  __ JumpToBuiltin(f);
+  // Perform tail call to the entry.
+  __ TailCallRuntime(f, 2);
 }
 
 
@@ -715,9 +710,8 @@ void StoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ push(eax);
   __ push(ebx);
 
-  // Set the number of arguments and jump to the entry.
-  __ Set(eax, Immediate(2));  // not counting receiver.
-  __ JumpToBuiltin(f);
+  // Perform tail call to the entry.
+  __ TailCallRuntime(f, 3);
 }
 
 
@@ -740,8 +734,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ push(ecx);
 
   // Do tail-call to runtime routine.
-  __ Set(eax, Immediate(2));  // not counting receiver
-  __ JumpToBuiltin(f);
+  __ TailCallRuntime(f, 3);
 }
 
 
index 6319ba945505bdcd3fba094791d0f2cd239bf9b7..b474e9f4d63cf871f7b3151f59d32d45fcde4e8d 100644 (file)
--- a/src/ic.h
+++ b/src/ic.h
@@ -128,8 +128,6 @@ class IC {
   static inline void SetTargetAtAddress(Address address, Code* target);
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
-
   // Frame pointer for the frame that uses (calls) the IC.
   Address fp_;
 
@@ -138,6 +136,8 @@ class IC {
   // GetProperty and SetProperty are called and they in turn might
   // invoke the garbage collector.
   Address* pc_address_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
 };
 
 
index bf81510a552d9a6c40b787cf134c075fcba67c77..21fcea420857d34597ebb854d2ad412e96e2200b 100644 (file)
@@ -174,30 +174,6 @@ void MacroAssembler::Ret() {
 }
 
 
-void MacroAssembler::Push(const Operand& src) {
-  push(r0);
-  mov(r0, src);
-}
-
-
-void MacroAssembler::Push(const MemOperand& src) {
-  push(r0);
-  ldr(r0, src);
-}
-
-
-void MacroAssembler::Pop(Register dst) {
-  mov(dst, Operand(r0));
-  pop(r0);
-}
-
-
-void MacroAssembler::Pop(const MemOperand& dst) {
-  str(r0, dst);
-  pop(r0);
-}
-
-
 // Will clobber 4 registers: object, offset, scratch, ip.  The
 // register 'object' contains a heap object pointer.  The heap object
 // tag is shifted away.
@@ -320,7 +296,7 @@ void MacroAssembler::EnterJSFrame(int argc) {
   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
-  // r0: TOS (code slot == 0)
+  push(r0);
   // r1: preserved
 }
 
@@ -517,7 +493,6 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
   ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize);  // adjust this code
   // The pc (return address) is passed in register lr.
   if (try_location == IN_JAVASCRIPT) {
-    mov(r0, Operand(Smi::FromInt(StackHandler::kCodeNotPresent)));  // new TOS
     stm(db_w, sp, pp.bit() | fp.bit() | lr.bit());
     if (type == TRY_CATCH_HANDLER) {
       mov(r3, Operand(StackHandler::TRY_CATCH));
@@ -529,14 +504,14 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
     ldr(r1, MemOperand(r3));
     push(r1);  // next sp
     str(sp, MemOperand(r3));  // chain handler
-    // TOS is r0
+    mov(r0, Operand(Smi::FromInt(StackHandler::kCodeNotPresent)));  // new TOS
+    push(r0);
   } else {
     // Must preserve r0-r3, 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
     // exception to check fp before dereferencing it to restore the context.
-    mov(r5, Operand(Smi::FromInt(StackHandler::kCodeNotPresent)));  // new TOS
     mov(pp, Operand(0));  // set pp to NULL
     mov(ip, Operand(0));  // to save a NULL fp
     stm(db_w, sp, pp.bit() | ip.bit() | lr.bit());
@@ -546,6 +521,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
     ldr(r6, MemOperand(r7));
     push(r6);  // next sp
     str(sp, MemOperand(r7));  // chain handler
+    mov(r5, Operand(Smi::FromInt(StackHandler::kCodeNotPresent)));  // new TOS
     push(r5);  // flush TOS
   }
 }
@@ -670,29 +646,17 @@ void MacroAssembler::StubReturn(int argc) {
   Ret();
 }
 
+
 void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
-  ASSERT(num_arguments >= 1);  // must have receiver for call
+  // All parameters are on the stack.  r0 has the return value after call.
 
-  if (f->nargs < 0) {
-    // The number of arguments is not constant for this call, or we don't
-    // have an entry stub that pushes the value. Push it before the call.
-    push(r0);
-    // Receiver does not count as an argument.
-    mov(r0, Operand(num_arguments - 1));
-  } else {
-    ASSERT(f->nargs == num_arguments);
-    // TODO(1236192): Most runtime routines don't need the number of
-    // arguments passed in because it is constant. At some point we
-    // should remove this need and make the runtime routine entry code
-    // smarter.
-
-    // The number of arguments is fixed for this call.
-    // Set r0 correspondingly.
-    push(r0);
-    mov(r0, Operand(f->nargs - 1));  // receiver does not count as an argument
-  }
+  // Either the expected number of arguments is unknown, or the actual
+  // number of arguments match the expectation.
+  ASSERT(f->nargs < 0 || f->nargs == num_arguments);
 
-  RuntimeStub stub((Runtime::FunctionId) f->stub_id);
+  Runtime::FunctionId function_id =
+      static_cast<Runtime::FunctionId>(f->stub_id);
+  RuntimeStub stub(function_id, num_arguments);
   CallStub(&stub);
 }
 
@@ -702,8 +666,14 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) {
 }
 
 
-void MacroAssembler::TailCallRuntime(Runtime::Function* f) {
-  JumpToBuiltin(ExternalReference(f));  // tail call to runtime routine
+void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
+                                     int num_arguments) {
+  // TODO(1236192): Most runtime routines don't need the number of
+  // arguments passed in because it is constant. At some point we
+  // should remove this need and make the runtime routine entry code
+  // smarter.
+  mov(r0, Operand(num_arguments));
+  JumpToBuiltin(ext);
 }
 
 
@@ -781,10 +751,10 @@ void MacroAssembler::Abort(const char* msg) {
     RecordComment(msg);
   }
 #endif
-  push(r0);
   mov(r0, Operand(p0));
   push(r0);
   mov(r0, Operand(Smi::FromInt(p1 - p0)));
+  push(r0);
   CallRuntime(Runtime::kAbort, 2);
   // will not return here
 }
index 60a827de23dab186a88b3ab14f2d03b8d81ad6e5..00cf621587f79e6ee44ec9671d3cc4103823d91e 100644 (file)
@@ -102,12 +102,6 @@ class MacroAssembler: public Assembler {
   void ExitJSFrame(ExitJSFlag flag);
 
 
-  // Support functions.
-  void Push(const Operand& src);
-  void Push(const MemOperand& src);
-  void Pop(Register dst);
-  void Pop(const MemOperand& dst);
-
   // ---------------------------------------------------------------------------
   // JavaScript invokes
 
@@ -198,8 +192,8 @@ class MacroAssembler: public Assembler {
 
   // Tail call of a runtime routine (jump).
   // Like JumpToBuiltin, but also takes care of passing the number
-  // of parameters, if known.
-  void TailCallRuntime(Runtime::Function* f);
+  // of parameters.
+  void TailCallRuntime(const ExternalReference& ext, int num_arguments);
 
   // Jump to the builtin routine.
   void JumpToBuiltin(const ExternalReference& builtin);
index d6f2264cec08136a0a984187a0d99aed777f330b..c56d3349d160bc711bd1109ed39d636c269429d4 100644 (file)
@@ -530,38 +530,29 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) {
 
 
 void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
-  if (num_arguments < 1) {
-    // must have receiver for call
+  // If the expected number of arguments of the runtime function is
+  // constant, we check that the actual number of arguments match the
+  // expectation.
+  if (f->nargs >= 0 && f->nargs != num_arguments) {
     IllegalOperation();
     return;
   }
 
-  // TODO(1236192): Most runtime routines don't need the number of
-  // arguments passed in because it is constant. At some point we
-  // should remove this need and make the runtime routine entry code
-  // smarter.
-
-  if (f->nargs < 0) {
-    // The number of arguments is not constant for this call.
-    // Receiver does not count as an argument.
-    mov(Operand(eax), Immediate(num_arguments - 1));
-  } else {
-    if (f->nargs != num_arguments) {
-      IllegalOperation();
-      return;
-    }
-    // Receiver does not count as an argument.
-    mov(Operand(eax), Immediate(f->nargs - 1));
-  }
-
-  RuntimeStub stub((Runtime::FunctionId) f->stub_id);
+  Runtime::FunctionId function_id =
+      static_cast<Runtime::FunctionId>(f->stub_id);
+  RuntimeStub stub(function_id, num_arguments);
   CallStub(&stub);
 }
 
 
-
-void MacroAssembler::TailCallRuntime(Runtime::Function* f) {
-  JumpToBuiltin(ExternalReference(f));  // tail call to runtime routine
+void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
+                                     int num_arguments) {
+  // TODO(1236192): Most runtime routines don't need the number of
+  // arguments passed in because it is constant. At some point we
+  // should remove this need and make the runtime routine entry code
+  // smarter.
+  mov(Operand(eax), Immediate(num_arguments));
+  JumpToBuiltin(ext);
 }
 
 
index 0fad02de2fffcd3073385aa14001334d41410b23..b3aba9a712c8567b0f8cb18aa42cfb14cf6bdb7a 100644 (file)
@@ -196,8 +196,8 @@ class MacroAssembler: public Assembler {
 
   // Tail call of a runtime routine (jump).
   // Like JumpToBuiltin, but also takes care of passing the number
-  // of parameters, if known.
-  void TailCallRuntime(Runtime::Function* f);
+  // of arguments.
+  void TailCallRuntime(const ExternalReference& ext, int num_arguments);
 
   // Jump to the builtin routine.
   void JumpToBuiltin(const ExternalReference& ext);
index b28ee5edbb3aac901c0f148d6ba9dc4e56f9f068..0ec3bb0b0977ed34d1d3cd3d646888b0fa7a9c2a 100644 (file)
@@ -214,6 +214,44 @@ void MarkCompactCollector::Finish() {
 
 static MarkingStack marking_stack;
 
+
+inline HeapObject* ShortCircuitConsString(Object** p) {
+  // Optimization: If the heap object pointed to by p is a cons string whose
+  // right substring is Heap::empty_string, update it in place to its left
+  // substring.  Return the updated value.
+  //
+  // Here we assume that if we change *p, we replace it with a heap object
+  // (ie, the left substring of a cons string is always a heap object).
+  //
+  // The check performed is:
+  //   object->IsConsString() &&
+  //   (ConsString::cast(object)->second() == Heap::empty_string())
+  // except the maps for the object and its possible substrings might be
+  // marked.
+  HeapObject* object = HeapObject::cast(*p);
+  MapWord map_word = object->map_word();
+  map_word.ClearMark();
+  InstanceType type = map_word.ToMap()->instance_type();
+  if (type >= FIRST_NONSTRING_TYPE) return object;
+
+  StringRepresentationTag rep =
+      static_cast<StringRepresentationTag>(type & kStringRepresentationMask);
+  if (rep != kConsStringTag) return object;
+
+  Object* second = reinterpret_cast<ConsString*>(object)->second();
+  if (reinterpret_cast<String*>(second) != Heap::empty_string()) return object;
+
+  // Since we don't have the object's start, it is impossible to update the
+  // remembered set.  Therefore, we only replace the string with its left
+  // substring when the remembered set does not change.
+  Object* first = reinterpret_cast<ConsString*>(object)->first();
+  if (!Heap::InNewSpace(object) && Heap::InNewSpace(first)) return object;
+
+  *p = first;
+  return HeapObject::cast(first);
+}
+
+
 // Helper class for marking pointers in HeapObjects.
 class MarkingVisitor : public ObjectVisitor {
  public:
@@ -272,34 +310,9 @@ class MarkingVisitor : public ObjectVisitor {
  private:
   // Mark object pointed to by p.
   void MarkObjectByPointer(Object** p) {
-    Object* obj = *p;
-    if (!obj->IsHeapObject()) return;
-
-    // Optimization: Bypass ConsString object where right size is
-    // Heap::empty_string().
-    // Please note this checks performed equals:
-    //   object->IsConsString() &&
-    //   (ConsString::cast(object)->second() == Heap::empty_string())
-    // except the map for the object might be marked.
-    MapWord map_word = HeapObject::cast(obj)->map_word();
-    map_word.ClearMark();
-    InstanceType type = map_word.ToMap()->instance_type();
-    if ((type < FIRST_NONSTRING_TYPE) &&
-        (static_cast<StringRepresentationTag>(
-            type & kStringRepresentationMask) == kConsStringTag) &&
-        (reinterpret_cast<String*>(
-             reinterpret_cast<ConsString*>(obj)->second()) ==
-         Heap::empty_string())) {
-      // Since we don't have the object start it is impossible to update the
-      // remeber set quickly.  Therefore this optimization only is taking
-      // place when we can avoid changing.
-      Object* first = reinterpret_cast<ConsString*>(obj)->first();
-      if (Heap::InNewSpace(obj) || !Heap::InNewSpace(first)) {
-        obj = first;
-        *p = obj;
-      }
-    }
-    MarkCompactCollector::MarkObject(HeapObject::cast(obj));
+    if (!(*p)->IsHeapObject()) return;
+    HeapObject* object = ShortCircuitConsString(p);
+    MarkCompactCollector::MarkObject(object);
   }
 
   // Tells whether the mark sweep collection will perform compaction.
@@ -345,6 +358,48 @@ class MarkingVisitor : public ObjectVisitor {
 };
 
 
+// Visitor class for marking heap roots.
+class RootMarkingVisitor : public ObjectVisitor {
+ public:
+  void VisitPointer(Object** p) {
+    MarkObjectByPointer(p);
+  }
+
+  void VisitPointers(Object** start, Object** end) {
+    for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
+  }
+
+  MarkingVisitor* stack_visitor() { return &stack_visitor_; }
+
+ private:
+  MarkingVisitor stack_visitor_;
+
+  void MarkObjectByPointer(Object** p) {
+    if (!(*p)->IsHeapObject()) return;
+
+    // Replace flat cons strings in place.
+    HeapObject* object = ShortCircuitConsString(p);
+    if (object->IsMarked()) return;
+
+#ifdef DEBUG
+    MarkCompactCollector::UpdateLiveObjectCount(object);
+#endif
+    Map* map = object->map();
+    // Mark the object.
+    object->SetMark();
+    MarkCompactCollector::tracer()->increment_marked_count();
+    // Mark the map pointer and body, and push them on the marking stack.
+    MarkCompactCollector::MarkObject(map);
+    object->IterateBody(map->instance_type(), object->SizeFromMap(map),
+                        &stack_visitor_);
+
+    // Mark all the objects reachable from the map and body.  May leave
+    // overflowed objects in the heap.
+    MarkCompactCollector::EmptyMarkingStack(&stack_visitor_);
+  }
+};
+
+
 // Helper class for pruning the symbol table.
 class SymbolTableCleaner : public ObjectVisitor {
  public:
@@ -368,26 +423,21 @@ class SymbolTableCleaner : public ObjectVisitor {
 };
 
 
-void MarkCompactCollector::MarkUnmarkedObject(HeapObject* obj) {
+void MarkCompactCollector::MarkUnmarkedObject(HeapObject* object) {
 #ifdef DEBUG
-  UpdateLiveObjectCount(obj);
+  UpdateLiveObjectCount(object);
 #endif
-  ASSERT(!obj->IsMarked());
-  if (obj->IsJSGlobalObject()) Counters::global_objects.Increment();
+  ASSERT(!object->IsMarked());
+  if (object->IsJSGlobalObject()) Counters::global_objects.Increment();
 
-  if (FLAG_cleanup_caches_in_maps_at_gc && obj->IsMap()) {
-    Map::cast(obj)->ClearCodeCache();
+  if (FLAG_cleanup_caches_in_maps_at_gc && object->IsMap()) {
+    Map::cast(object)->ClearCodeCache();
   }
 
-  obj->SetMark();
+  object->SetMark();
   tracer_->increment_marked_count();
-  if (!marking_stack.overflowed()) {
-    ASSERT(Heap::Contains(obj));
-    marking_stack.Push(obj);
-  } else {
-    // Set object's stack overflow bit, wait for rescan.
-    obj->SetOverflow();
-  }
+  ASSERT(Heap::Contains(object));
+  marking_stack.Push(object);
 }
 
 
@@ -401,26 +451,23 @@ static int OverflowObjectSize(HeapObject* obj) {
 }
 
 
-static bool VisitOverflowedObject(HeapObject* obj) {
-  if (!obj->IsOverflowed()) return true;
-  ASSERT(obj->IsMarked());
-
-  if (marking_stack.overflowed()) return false;
-
-  obj->ClearOverflow();
-  ASSERT(Heap::Contains(obj));
-  marking_stack.Push(obj);
-  return true;
-}
-
-
+// Fill the marking stack with overflowed objects returned by the given
+// iterator.  Stop when the marking stack is filled or the end of the space
+// is reached, whichever comes first.
 template<class T>
 static void ScanOverflowedObjects(T* it) {
+  // The caller should ensure that the marking stack is initially not full,
+  // so that we don't waste effort pointlessly scanning for objects.
+  ASSERT(!marking_stack.is_full());
+
   while (it->has_next()) {
-    HeapObject* obj = it->next();
-    if (!VisitOverflowedObject(obj)) {
-      ASSERT(marking_stack.overflowed());
-      break;
+    HeapObject* object = it->next();
+    if (object->IsOverflowed()) {
+      object->ClearOverflow();
+      ASSERT(object->IsMarked());
+      ASSERT(Heap::Contains(object));
+      marking_stack.Push(object);
+      if (marking_stack.is_full()) return;
     }
   }
 }
@@ -433,15 +480,15 @@ bool MarkCompactCollector::MustBeMarked(Object** p) {
 }
 
 
-void MarkCompactCollector::MarkStrongRoots(MarkingVisitor* marking_visitor) {
+void MarkCompactCollector::ProcessRoots(RootMarkingVisitor* visitor) {
   // Mark the heap roots gray, including global variables, stack variables,
   // etc.
-  Heap::IterateStrongRoots(marking_visitor);
+  Heap::IterateStrongRoots(visitor);
 
   // Take care of the symbol table specially.
   SymbolTable* symbol_table = SymbolTable::cast(Heap::symbol_table());
   // 1. Mark the prefix of the symbol table gray.
-  symbol_table->IteratePrefix(marking_visitor);
+  symbol_table->IteratePrefix(visitor);
 #ifdef DEBUG
   UpdateLiveObjectCount(symbol_table);
 #endif
@@ -449,6 +496,12 @@ void MarkCompactCollector::MarkStrongRoots(MarkingVisitor* marking_visitor) {
   // or mark it overflowed).
   symbol_table->SetMark();
   tracer_->increment_marked_count();
+
+  // There may be overflowed objects in the heap.  Visit them now.
+  while (marking_stack.overflowed()) {
+    RefillMarkingStack();
+    EmptyMarkingStack(visitor->stack_visitor());
+  }
 }
 
 
@@ -486,70 +539,82 @@ void MarkCompactCollector::MarkObjectGroups() {
 }
 
 
-// Mark as black all objects reachable starting from gray objects.  (Gray
-// objects are marked and on the marking stack, or marked and marked as
-// overflowed and not on the marking stack).
-//
-// Before: the heap contains a mixture of white, gray, and black objects.
-// After: the heap contains a mixture of white and black objects.
-void MarkCompactCollector::ProcessMarkingStack(
-    MarkingVisitor* marking_visitor) {
-
-  while (true) {
-    while (!marking_stack.is_empty()) {
-      HeapObject* object = marking_stack.Pop();
-      ASSERT(object->IsHeapObject());
-      ASSERT(Heap::Contains(object));
-      // Removing a (gray) object from the marking stack turns it black.
-      ASSERT(object->IsMarked() && !object->IsOverflowed());
-
-      // Because the object is marked, we have to recover the original map
-      // pointer and use it to mark the object's body.
-      MapWord map_word = object->map_word();
-      map_word.ClearMark();
-      Map* map = map_word.ToMap();
-      MarkObject(map);
-      object->IterateBody(map->instance_type(), object->SizeFromMap(map),
-                          marking_visitor);
-    }
+// Mark all objects reachable from the objects on the marking stack.
+// Before: the marking stack contains zero or more heap object pointers.
+// After: the marking stack is empty, and all objects reachable from the
+// marking stack have been marked, or are overflowed in the heap.
+void MarkCompactCollector::EmptyMarkingStack(MarkingVisitor* visitor) {
+  while (!marking_stack.is_empty()) {
+    HeapObject* object = marking_stack.Pop();
+    ASSERT(object->IsHeapObject());
+    ASSERT(Heap::Contains(object));
+    ASSERT(object->IsMarked());
+    ASSERT(!object->IsOverflowed());
+
+    // Because the object is marked, we have to recover the original map
+    // pointer and use it to mark the object's body.
+    MapWord map_word = object->map_word();
+    map_word.ClearMark();
+    Map* map = map_word.ToMap();
+    MarkObject(map);
+    object->IterateBody(map->instance_type(), object->SizeFromMap(map),
+                        visitor);
+  }
+}
+
 
-    // The only gray objects are marked overflowed in the heap.  If there
-    // are any, refill the marking stack and continue.
-    if (!marking_stack.overflowed()) return;
+// Sweep the heap for overflowed objects, clear their overflow bits, and
+// push them on the marking stack.  Stop early if the marking stack fills
+// before sweeping completes.  If sweeping completes, there are no remaining
+// overflowed objects in the heap so the overflow flag on the markings stack
+// is cleared.
+void MarkCompactCollector::RefillMarkingStack() {
+  ASSERT(marking_stack.overflowed());
 
-    marking_stack.clear_overflowed();
-    // We have early stops if the marking stack overflows while refilling it
-    // with gray objects to avoid pointlessly scanning extra spaces.
-    SemiSpaceIterator new_it(Heap::new_space(), &OverflowObjectSize);
-    ScanOverflowedObjects(&new_it);
-    if (marking_stack.overflowed()) continue;
+  SemiSpaceIterator new_it(Heap::new_space(), &OverflowObjectSize);
+  ScanOverflowedObjects(&new_it);
+  if (marking_stack.is_full()) return;
 
-    HeapObjectIterator old_it(Heap::old_space(), &OverflowObjectSize);
-    ScanOverflowedObjects(&old_it);
-    if (marking_stack.overflowed()) continue;
+  HeapObjectIterator old_it(Heap::old_space(), &OverflowObjectSize);
+  ScanOverflowedObjects(&old_it);
+  if (marking_stack.is_full()) return;
 
-    HeapObjectIterator code_it(Heap::code_space(), &OverflowObjectSize);
-    ScanOverflowedObjects(&code_it);
-    if (marking_stack.overflowed()) continue;
+  HeapObjectIterator code_it(Heap::code_space(), &OverflowObjectSize);
+  ScanOverflowedObjects(&code_it);
+  if (marking_stack.is_full()) return;
 
-    HeapObjectIterator map_it(Heap::map_space(), &OverflowObjectSize);
-    ScanOverflowedObjects(&map_it);
-    if (marking_stack.overflowed()) continue;
+  HeapObjectIterator map_it(Heap::map_space(), &OverflowObjectSize);
+  ScanOverflowedObjects(&map_it);
+  if (marking_stack.is_full()) return;
 
-    LargeObjectIterator lo_it(Heap::lo_space(), &OverflowObjectSize);
-    ScanOverflowedObjects(&lo_it);
+  LargeObjectIterator lo_it(Heap::lo_space(), &OverflowObjectSize);
+  ScanOverflowedObjects(&lo_it);
+  if (marking_stack.is_full()) return;
+
+  marking_stack.clear_overflowed();
+}
+
+
+// Mark all objects reachable (transitively) from objects on the marking
+// stack.  Before: the marking stack contains zero or more heap object
+// pointers.  After: the marking stack is empty and there are no overflowed
+// objects in the heap.
+void MarkCompactCollector::ProcessMarkingStack(MarkingVisitor* visitor) {
+  EmptyMarkingStack(visitor);
+  while (marking_stack.overflowed()) {
+    RefillMarkingStack();
+    EmptyMarkingStack(visitor);
   }
 }
 
 
-void MarkCompactCollector::ProcessObjectGroups(
-    MarkingVisitor* marking_visitor) {
+void MarkCompactCollector::ProcessObjectGroups(MarkingVisitor* visitor) {
   bool work_to_do = true;
   ASSERT(marking_stack.is_empty());
   while (work_to_do) {
     MarkObjectGroups();
     work_to_do = !marking_stack.is_empty();
-    ProcessMarkingStack(marking_visitor);
+    ProcessMarkingStack(visitor);
   }
 }
 
@@ -566,15 +631,14 @@ void MarkCompactCollector::MarkLiveObjects() {
 
   ASSERT(!marking_stack.overflowed());
 
-  MarkingVisitor marking_visitor;
-  MarkStrongRoots(&marking_visitor);
-  ProcessMarkingStack(&marking_visitor);
+  RootMarkingVisitor root_visitor;
+  ProcessRoots(&root_visitor);
 
   // The objects reachable from the roots are marked black, unreachable
   // objects are white.  Mark objects reachable from object groups with at
   // least one marked object, and continue until no new objects are
   // reachable from the object groups.
-  ProcessObjectGroups(&marking_visitor);
+  ProcessObjectGroups(root_visitor.stack_visitor());
 
   // The objects reachable from the roots or object groups are marked black,
   // unreachable objects are white.  Process objects reachable only from
@@ -583,12 +647,15 @@ void MarkCompactCollector::MarkLiveObjects() {
   // First we mark weak pointers not yet reachable.
   GlobalHandles::MarkWeakRoots(&MustBeMarked);
   // Then we process weak pointers and process the transitive closure.
-  GlobalHandles::IterateWeakRoots(&marking_visitor);
-  ProcessMarkingStack(&marking_visitor);
+  GlobalHandles::IterateWeakRoots(&root_visitor);
+  while (marking_stack.overflowed()) {
+    RefillMarkingStack();
+    EmptyMarkingStack(root_visitor.stack_visitor());
+  }
 
   // Repeat the object groups to mark unmarked groups reachable from the
   // weak roots.
-  ProcessObjectGroups(&marking_visitor);
+  ProcessObjectGroups(root_visitor.stack_visitor());
 
   // Prune the symbol table removing all symbols only pointed to by the
   // symbol table.  Cannot use SymbolTable::cast here because the symbol
index d4dcdc7a2a56dff1ead3ee08959a01f7c587cd8d..7ab6d32b5c93bacaf66db3ba71e07e7eb952984d 100644 (file)
@@ -39,9 +39,11 @@ typedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset);
 typedef void (*DeallocateFunction)(Address start, int size_in_bytes);
 
 
-// Forward declaration of visitor.
+// Forward declarations.
+class RootMarkingVisitor;
 class MarkingVisitor;
 
+
 // ----------------------------------------------------------------------------
 // Mark-Compact collector
 //
@@ -141,16 +143,11 @@ class MarkCompactCollector : public AllStatic {
   //
   //    after: live objects are marked.
 
+  friend class RootMarkingVisitor;
   friend class MarkingVisitor;
 
   // Marking operations for objects reachable from roots.
   static void MarkLiveObjects();
-  static void UnmarkLiveObjects();
-
-  // Visit overflowed object, push overflowed object on the marking stack and
-  // clear the overflow bit. If the marking stack is overflowed during this
-  // process, return false;
-  static bool VisitOverflowedObject(HeapObject* obj);
 
   static void MarkUnmarkedObject(HeapObject* obj);
 
@@ -158,8 +155,8 @@ class MarkCompactCollector : public AllStatic {
      if (!obj->IsMarked()) MarkUnmarkedObject(obj);
   }
 
-  // Mark the heap roots.
-  static void MarkStrongRoots(MarkingVisitor* marking_visitor);
+  // Mark the heap roots and all objects reachable from them.
+  static void ProcessRoots(RootMarkingVisitor* visitor);
 
   // Mark objects in object groups that have at least one object in the
   // group marked.
@@ -168,11 +165,22 @@ class MarkCompactCollector : public AllStatic {
   // Mark all objects in an object group with at least one marked
   // object, then all objects reachable from marked objects in object
   // groups, and repeat.
-  static void ProcessObjectGroups(MarkingVisitor* marking_visitor);
-
-  // Mark all objects reachable (transitively) from objects in the
-  // marking stack or marked as overflowed in the heap.
-  static void ProcessMarkingStack(MarkingVisitor* marking_visitor);
+  static void ProcessObjectGroups(MarkingVisitor* visitor);
+
+  // Mark objects reachable (transitively) from objects in the marking stack
+  // or overflowed in the heap.
+  static void ProcessMarkingStack(MarkingVisitor* visitor);
+
+  // Mark objects reachable (transitively) from objects in the marking
+  // stack.  This function empties the marking stack, but may leave
+  // overflowed objects in the heap, in which case the marking stack's
+  // overflow flag will be set.
+  static void EmptyMarkingStack(MarkingVisitor* visitor);
+
+  // Refill the marking stack with overflowed objects from the heap.  This
+  // function either leaves the marking stack full or clears the overflow
+  // flag on the marking stack.
+  static void RefillMarkingStack();
 
   // Callback function for telling whether the object *p must be marked.
   static bool MustBeMarked(Object** p);
index eb4a4cc1acf953d4329a643d7b53546840df08a2..12bf70d1a71cf54ee22dfb9927566116744646e0 100644 (file)
@@ -41,9 +41,7 @@ $Math.__proto__ = global.Object.prototype;
 %AddProperty(global, "Math", $Math, DONT_ENUM);
 
 
-// TODO(1240985): Make this work without arguments to the runtime
-// call.
-function $Math_random() { return %Math_random(0); }
+function $Math_random() { return %Math_random(); }
 %AddProperty($Math, "random", $Math_random, DONT_ENUM);
 
 function $Math_abs(x) {
index 264114558df0efcd5d0d6bc274e0ce8ed644cbc5..1630122e991376850c19f92b59536b7be7d45868 100644 (file)
@@ -639,7 +639,7 @@ function DefineError(name) {
   f.prototype.name = name;
   f.prototype.constructor = f;
   %SetCode(f, function(m) {
-    if (%IsConstructCall(this)) {
+    if (%IsConstructCall()) {
       if (!IS_UNDEFINED(m)) this.message = ToString(m);
     } else {
       return new f(m);
index c70ab16df6bc17f147db13847cf8b660fa616358..d12b7d309e2cdcb591a4e90abb98dfefe3128604 100644 (file)
@@ -594,16 +594,9 @@ void Oddball::OddballVerify() {
 
 void Code::CodePrint() {
   HeapObject::PrintHeader("Code");
-  PrintF("kind = %s", Kind2String(kind()));
-
-  PrintF("\nInstructions (size = %d)\n", instruction_size());
-  Disassembler::Decode(NULL /*use PrintF*/, this);
-  PrintF("\n");
-
-  PrintF("RelocInfo (size = %d)\n", relocation_size());
-  for (RelocIterator it(this); !it.done(); it.next())
-    it.rinfo()->Print();
-  PrintF("\n");
+#ifdef ENABLE_DISASSEMBLER
+  Disassemble();
+#endif
 }
 
 
index 5527cfbc35469d16b15a2c2ce4396203951bd6fa..4bda9cc75698c3df5739951f6e8571595f180ec9 100644 (file)
 #include "scopeinfo.h"
 #include "string-stream.h"
 
+#ifdef ENABLE_DISASSEMBLER
+#include "disassembler.h"
+#endif
+
 namespace v8 { namespace internal {
 
 #ifdef DEBUG
@@ -985,7 +989,6 @@ Object* JSObject::AddFastProperty(String* name,
     Object* r = old_descriptors->CopyRemove(name);
     if (r->IsFailure()) return r;
     old_descriptors = DescriptorArray::cast(r);
-    map()->set_instance_descriptors(old_descriptors);
     old_name_index = DescriptorArray::kNotFound;
   }
 
@@ -995,35 +998,35 @@ Object* JSObject::AddFastProperty(String* name,
   // Allocate new instance descriptors with (name, index) added
   FieldDescriptor new_field(name, index, attributes);
   Object* new_descriptors =
-      map()->instance_descriptors()->CopyInsert(&new_field, true);
+      old_descriptors->CopyInsert(&new_field, true);
   if (new_descriptors->IsFailure()) return new_descriptors;
 
   // Only allow map transition if the object's map is NOT equal to the
   // global object_function's map and there is not a transition for name.
   bool allow_map_transition =
-        !map()->instance_descriptors()->Contains(name) &&
+        !old_descriptors->Contains(name) &&
         (Top::context()->global_context()->object_function()->map() != map());
   ASSERT(allow_map_transition || !constant_transition);
 
   if (map()->unused_property_fields() > 0) {
     ASSERT(index < properties()->length());
     // Allocate a new map for the object.
-    Object* new_map = map()->Copy();
-    if (new_map->IsFailure()) return new_map;
+    Object* r = map()->Copy();
+    if (r->IsFailure()) return r;
+    Map* new_map = Map::cast(r);
     if (allow_map_transition) {
       // Allocate new instance descriptors for the old map with map transition.
       MapTransitionDescriptor d(name, Map::cast(new_map), attributes);
-      Object* old_descriptors = map()->instance_descriptors()->CopyInsert(&d);
-      if (old_descriptors->IsFailure()) return old_descriptors;
-      // We have now allocate all the necessary object and change can be
-      // applied.
-      map()->set_instance_descriptors(DescriptorArray::cast(old_descriptors));
+      Object* r = old_descriptors->CopyInsert(&d);
+      if (r->IsFailure()) return r;
+      old_descriptors = DescriptorArray::cast(r);
     }
-    Map::cast(new_map)->
-      set_instance_descriptors(DescriptorArray::cast(new_descriptors));
-    Map::cast(new_map)->
-      set_unused_property_fields(map()->unused_property_fields() - 1);
-    set_map(Map::cast(new_map));
+    // We have now allocated all the necessary objects.
+    // All the changes can be applied at once, so they are atomic.
+    map()->set_instance_descriptors(old_descriptors);
+    new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
+    new_map->set_unused_property_fields(map()->unused_property_fields() - 1);
+    set_map(new_map);
     properties()->set(index, value);
   } else {
     ASSERT(map()->unused_property_fields() == 0);
@@ -1043,26 +1046,23 @@ Object* JSObject::AddFastProperty(String* name,
     FixedArray::cast(values)->set(index, value);
 
     // Allocate a new map for the object.
-    Object* new_map = map()->Copy();
-    if (new_map->IsFailure()) return new_map;
+    Object* r = map()->Copy();
+    if (r->IsFailure()) return r;
+    Map* new_map = Map::cast(r);
 
     if (allow_map_transition) {
       MapTransitionDescriptor d(name, Map::cast(new_map), attributes);
-      // Allocate a new instance descriptors for the old map with map
-      // transition.
-      Object* old_descriptors = map()->instance_descriptors()->CopyInsert(&d);
-      if (old_descriptors->IsFailure()) return old_descriptors;
-
-      // We have now allocate all the necessary object and change can be
-      // applied.
-      map()->set_instance_descriptors(DescriptorArray::cast(old_descriptors));
+      // Allocate new instance descriptors for the old map with map transition.
+      Object* r = old_descriptors->CopyInsert(&d);
+      if (r->IsFailure()) return r;
+      old_descriptors = DescriptorArray::cast(r);
     }
-
-    Map::cast(new_map)->
-      set_instance_descriptors(DescriptorArray::cast(new_descriptors));
-    Map::cast(new_map)->
-      set_unused_property_fields(kExtraFields - 1);
-    set_map(Map::cast(new_map));
+    // We have now allocated all the necessary objects.
+    // All changes can be done at once, atomically.
+    map()->set_instance_descriptors(old_descriptors);
+    new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
+    new_map->set_unused_property_fields(kExtraFields - 1);
+    set_map(new_map);
     set_properties(FixedArray::cast(values));
   }
 
@@ -1109,7 +1109,7 @@ Object* JSObject::AddConstantFunctionProperty(String* name,
   ConstTransitionDescriptor mark(name);
   new_descriptors = old_map->instance_descriptors()->CopyInsert(&mark, false);
   if (new_descriptors->IsFailure()) {
-    return new_descriptors;
+    return function;  // We have accomplished the main goal, so return success.
   }
   old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
 
@@ -4083,6 +4083,20 @@ const char* Code::Kind2String(Kind kind) {
   UNREACHABLE();
   return NULL;
 }
+
+
+void Code::Disassemble() {
+  PrintF("kind = %s", Kind2String(kind()));
+
+  PrintF("\nInstructions (size = %d)\n", instruction_size());
+  Disassembler::Decode(NULL, this);
+  PrintF("\n");
+
+  PrintF("RelocInfo (size = %d)\n", relocation_size());
+  for (RelocIterator it(this); !it.done(); it.next())
+    it.rinfo()->Print();
+  PrintF("\n");
+}
 #endif  // ENABLE_DISASSEMBLER
 
 
index 4b1f8c89967a80e1f76ce5f9ba9254a1eff530da..e337b54ed3bb8a3e4384f54b3c4a97da34b6cade 100644 (file)
@@ -2030,6 +2030,7 @@ class Code: public HeapObject {
 #ifdef ENABLE_DISASSEMBLER
   // Printing
   static const char* Kind2String(Kind kind);
+  void Disassemble();
 #endif  // ENABLE_DISASSEMBLER
 
   // [instruction_size]: Size of the native instructions
@@ -2195,15 +2196,6 @@ class Map: public HeapObject {
   inline byte bit_field();
   inline void set_bit_field(byte value);
 
-  // Tells whether this object has a special lookup behavior.
-  void set_special_lookup() {
-    set_bit_field(bit_field() | (1 << kHasSpecialLookup));
-  }
-
-  bool has_special_lookup() {
-    return ((1 << kHasSpecialLookup) & bit_field()) != 0;
-  }
-
   // Tells whether the object in the prototype property will be used
   // for instances created from this function.  If the prototype
   // property is set to a value that is not a JSObject, the prototype
@@ -2343,7 +2335,7 @@ class Map: public HeapObject {
   static const int kBitFieldOffset = kInstanceAttributesOffset + 3;
 
   // Bit positions for bit field.
-  static const int kHasSpecialLookup = 0;
+  static const int kUnused = 0;  // To be used for marking recently used maps.
   static const int kHasNonInstancePrototype = 1;
   static const int kIsHiddenPrototype = 2;
   static const int kHasNamedInterceptor = 3;
@@ -2374,7 +2366,7 @@ enum ScriptType {
 };
 
 
-// Script describes a script which has beed added to the VM.
+// Script describes a script which has been added to the VM.
 class Script: public Struct {
  public:
   // [source]: the script source.
@@ -2528,8 +2520,6 @@ class SharedFunctionInfo: public HeapObject {
   static const int kSize = kDebugInfoOffset + kPointerSize;
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
-
   // Bit positions in length_and_flg.
   // The least significant bit is used as the flag.
   static const int kFlagBit         = 0;
@@ -2543,6 +2533,8 @@ class SharedFunctionInfo: public HeapObject {
   static const int kIsTopLevelBit   = 1;
   static const int kStartPositionShift = 2;
   static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
 };
 
 
@@ -2652,8 +2644,9 @@ class GlobalObject: public JSObject {
   static const int kHeaderSize = kGlobalContextOffset + kPointerSize;
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject);
   friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject);
 };
 
 
@@ -3406,12 +3399,12 @@ class AccessorInfo: public Struct {
   static const int kSize = kFlagOffset + kPointerSize;
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
-
   // Bit positions in flag.
   static const int kAllCanReadBit  = 0;
   static const int kAllCanWriteBit = 1;
   class AttributesField: public BitField<PropertyAttributes, 2, 3> {};
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
 };
 
 
@@ -3561,12 +3554,12 @@ class FunctionTemplateInfo: public TemplateInfo {
   static const int kSize = kFlagOffset + kPointerSize;
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
-
   // Bit position in the flag, from least significant bit position.
   static const int kHiddenPrototypeBit   = 0;
   static const int kUndetectableBit      = 1;
   static const int kNeedsAccessCheckBit  = 2;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
 };
 
 
index e7f1144e99c9541d7d50303dbcb3238edfc0addf..c5aea63f27e94512c2444657e57a155ecaa5d4cd 100644 (file)
@@ -213,9 +213,9 @@ class OS {
   static double nan_value();
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(OS);
-
   static const int msPerSecond = 1000;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(OS);
 };
 
 
index 473483317ce1df3ad2a29830e96061356df6b393..320e65bd16c18aaacf9881bbff569af31e6f39fb 100644 (file)
@@ -105,7 +105,7 @@ function DoConstructRegExp(object, pattern, flags, isConstructorCall) {
 
 
 function RegExpConstructor(pattern, flags) {
-  if (%IsConstructCall(this)) {
+  if (%IsConstructCall()) {
     DoConstructRegExp(this, pattern, flags, true);
   } else {
     // RegExp : Called as function; see ECMA-262, section 15.10.3.1.
index 5f2298057648d4749ad26bd84a8a9b6e267f91a9..4d53cebdad20789651ee3bb3150c9e81c7126f03 100644 (file)
@@ -201,17 +201,12 @@ static Object* Runtime_IsInPrototypeChain(Arguments args) {
 
 static Object* Runtime_IsConstructCall(Arguments args) {
   NoHandleAllocation ha;
+  ASSERT(args.length() == 0);
   JavaScriptFrameIterator it;
   return Heap::ToBoolean(it.frame()->IsConstructor());
 }
 
 
-static Object* Runtime_GetBuiltins(Arguments args) {
-  NoHandleAllocation ha;
-  return Top::context()->builtins();
-}
-
-
 static Object* Runtime_RegExpCompile(Arguments args) {
   HandleScope scope;  // create a new handle scope
   ASSERT(args.length() == 3);
@@ -1875,7 +1870,7 @@ static Object* ConvertCase(Arguments args,
   // with the exact length.  This is implemented using a goto back
   // to this label if we discover that the assumption doesn't hold.
   // I apologize sincerely for this and will give a vaffel-is to
-  // anyone who can implement it in a nicer way.
+  // the first person who can implement it in a nicer way.
  try_convert:
 
   // Allocate the resulting string.
@@ -2079,13 +2074,6 @@ static Object* Runtime_NumberMul(Arguments args) {
 }
 
 
-static Object* Runtime_NumberAlloc(Arguments args) {
-  NoHandleAllocation ha;
-  ASSERT(args.length() == 1);
-  return Heap::AllocateHeapNumber(0);
-}
-
-
 static Object* Runtime_NumberUnaryMinus(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 1);
@@ -2539,8 +2527,9 @@ static Object* Runtime_Math_pow(Arguments args) {
 
 // Returns a number value with positive sign, greater than or equal to
 // 0 but less than 1, chosen randomly.
-static Object* Runtime_Math_random(Arguments) {
+static Object* Runtime_Math_random(Arguments args) {
   NoHandleAllocation ha;
+  ASSERT(args.length() == 0);
 
   // To get much better precision, we combine the results of two
   // invocations of random(). The result is computed by normalizing a
@@ -2704,7 +2693,7 @@ static Object* Runtime_LazyCompile(Arguments args) {
 
 static Object* Runtime_GetCalledFunction(Arguments args) {
   HandleScope scope;
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 0);
   StackFrameIterator it;
   // Get past the JS-to-C exit frame.
   ASSERT(it.frame()->is_exit());
@@ -3177,8 +3166,9 @@ static Object* Runtime_DebugTrace(Arguments args) {
 }
 
 
-static Object* Runtime_DateCurrentTime(Arguments) {
+static Object* Runtime_DateCurrentTime(Arguments args) {
   NoHandleAllocation ha;
+  ASSERT(args.length() == 0);
 
   // According to ECMA-262, section 15.9.1, page 117, the precision of
   // the number in a Date object representing a particular instant in
@@ -3217,7 +3207,7 @@ static Object* Runtime_DateLocalTimezone(Arguments args) {
 
 static Object* Runtime_DateLocalTimeOffset(Arguments args) {
   NoHandleAllocation ha;
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 0);
 
   return Heap::NumberFromDouble(OS::LocalTimeOffset());
 }
@@ -3247,22 +3237,25 @@ static Object* Runtime_NumberIsFinite(Arguments args) {
 }
 
 
-static Object* Runtime_NumberMaxValue(Arguments) {
+static Object* Runtime_NumberMaxValue(Arguments args) {
   NoHandleAllocation ha;
+  ASSERT(args.length() == 0);
 
   return Heap::number_max_value();
 }
 
 
-static Object* Runtime_NumberMinValue(Arguments) {
+static Object* Runtime_NumberMinValue(Arguments args) {
   NoHandleAllocation ha;
+  ASSERT(args.length() == 0);
 
   return Heap::number_min_value();
 }
 
 
-static Object* Runtime_NumberNaN(Arguments) {
+static Object* Runtime_NumberNaN(Arguments args) {
   NoHandleAllocation ha;
+  ASSERT(args.length() == 0);
 
   return Heap::nan_value();
 }
@@ -3550,7 +3543,7 @@ static Object* Runtime_RemoveDebugEventListener(Arguments args) {
 
 
 static Object* Runtime_Break(Arguments args) {
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 0);
   StackGuard::DebugBreak();
   return Heap::undefined_value();
 }
@@ -4262,7 +4255,7 @@ static Object* Runtime_PrepareStep(Arguments args) {
 // Clear all stepping set by PrepareStep.
 static Object* Runtime_ClearStepping(Arguments args) {
   HandleScope scope;
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 0);
   Debug::ClearStepping();
   return Heap::undefined_value();
 }
@@ -4545,7 +4538,7 @@ static int DebugGetLoadedScripts(FixedArray* instances, int instances_size) {
 
 static Object* Runtime_DebugGetLoadedScripts(Arguments args) {
   HandleScope scope;
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 0);
 
   // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
   // rid of all the cached script wrappes and the second gets rid of the
@@ -4773,6 +4766,7 @@ static Object* Runtime_GetPrototype(Arguments args) {
 
 
 static Object* Runtime_SystemBreak(Arguments args) {
+  ASSERT(args.length() == 0);
   CPU::DebugBreak();
   return Heap::undefined_value();
 }
@@ -4857,7 +4851,7 @@ static Object* Runtime_Abort(Arguments args) {
 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
 // Exclude the code in release mode.
 static Object* Runtime_ListNatives(Arguments args) {
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 0);
   HandleScope scope;
   Handle<JSArray> result = Factory::NewJSArray(0);
   int index = 0;
index 0e0ae9747718ab141b8a55ea091fe21edb3c6ef9..564a36f314c6d4df3c98150b066935ad249407cc 100644 (file)
@@ -52,11 +52,10 @@ namespace v8 { namespace internal {
   \
   F(IsInPrototypeChain, 2) \
   \
-  F(IsConstructCall, 1) \
+  F(IsConstructCall, 0) \
   \
   /* Utilities */ \
-  F(GetBuiltins, 1) \
-  F(GetCalledFunction, 1) \
+  F(GetCalledFunction, 0) \
   F(GetFunctionDelegate, 1) \
   F(NewArguments, 1) \
   F(LazyCompile, 1) \
@@ -91,7 +90,6 @@ namespace v8 { namespace internal {
   F(NumberMul, 2) \
   F(NumberDiv, 2) \
   F(NumberMod, 2) \
-  F(NumberAlloc, 1) \
   F(NumberUnaryMinus, 1) \
   \
   F(StringAdd, 2) \
@@ -127,7 +125,7 @@ namespace v8 { namespace internal {
   F(Math_floor, 1) \
   F(Math_log, 1) \
   F(Math_pow, 2) \
-  F(Math_random, 1) \
+  F(Math_random, 0) \
   F(Math_round, 1) \
   F(Math_sin, 1) \
   F(Math_sqrt, 1) \
@@ -169,17 +167,17 @@ namespace v8 { namespace internal {
   F(GetTemplateField, 2) \
   \
   /* Dates */ \
-  F(DateCurrentTime, 1) \
+  F(DateCurrentTime, 0) \
   F(DateParseString, 1) \
   F(DateLocalTimezone, 1) \
-  F(DateLocalTimeOffset, 1) \
+  F(DateLocalTimeOffset, 0) \
   F(DateDaylightSavingsOffset, 1) \
   \
   /* Numbers */ \
   F(NumberIsFinite, 1) \
-  F(NumberMaxValue, 1) \
-  F(NumberMinValue, 1) \
-  F(NumberNaN, 1) \
+  F(NumberMaxValue, 0) \
+  F(NumberMinValue, 0) \
+  F(NumberNaN, 0) \
   \
   /* Globals */ \
   F(CompileString, 2) \
@@ -205,7 +203,7 @@ namespace v8 { namespace internal {
   /* Debugging */ \
   F(AddDebugEventListener, 2) \
   F(RemoveDebugEventListener, 1) \
-  F(Break, 1) \
+  F(Break, 0) \
   F(DebugGetLocalPropertyDetails, 2) \
   F(DebugGetProperty, 2) \
   F(DebugLocalPropertyNames, 1) \
@@ -228,14 +226,14 @@ namespace v8 { namespace internal {
   F(ClearBreakPoint, 1) \
   F(ChangeBreakOnException, 2) \
   F(PrepareStep, 3) \
-  F(ClearStepping, 1) \
+  F(ClearStepping, 0) \
   F(DebugEvaluate, 4) \
   F(DebugEvaluateGlobal, 3) \
-  F(DebugGetLoadedScripts, 1) \
+  F(DebugGetLoadedScripts, 0) \
   F(DebugReferencedBy, 3) \
   F(DebugConstructedBy, 2) \
   F(GetPrototype, 1) \
-  F(SystemBreak, 1) \
+  F(SystemBreak, 0) \
   \
   /* Literals */ \
   F(MaterializeRegExpLiteral, 4)\
@@ -263,7 +261,7 @@ namespace v8 { namespace internal {
   F(DeclareGlobals, 3) \
   F(DeclareContextSlot, 5) \
   F(InitializeVarGlobal, -1 /* 1 or 2 */) \
-  F(InitializeConstGlobal, -1 /* 1 or 2 */) \
+  F(InitializeConstGlobal, 2) \
   F(InitializeConstContextSlot, 3) \
   \
   /* Debugging */ \
@@ -282,7 +280,7 @@ namespace v8 { namespace internal {
 #ifdef DEBUG
 #define RUNTIME_FUNCTION_LIST_DEBUG(F) \
   /* Testing */ \
-  F(ListNatives, 1)
+  F(ListNatives, 0)
 #else
 #define RUNTIME_FUNCTION_LIST_DEBUG(F)
 #endif
index e518c5bba04d3a2e689ee60b4a129d7e600341a4..37939e7cf0fccf43895bad6d1f2da56c6d18f80a 100644 (file)
@@ -47,7 +47,7 @@ const $String = global.String;
 const $Number = global.Number;
 const $Function = global.Function;
 const $Boolean = global.Boolean;
-const $NaN = %NumberNaN(1);
+const $NaN = %NumberNaN();
 
 
 // ECMA-262, section 11.9.1, page 55.
@@ -317,7 +317,7 @@ function FILTER_KEY(key) {
 
 
 function CALL_NON_FUNCTION() {
-  var callee = %GetCalledFunction(0);
+  var callee = %GetCalledFunction();
   var delegate = %GetFunctionDelegate(callee);
   if (!IS_FUNCTION(delegate)) {
     throw %MakeTypeError('called_non_callable', [typeof callee]);
@@ -408,7 +408,7 @@ function ToNumber(x) {
   if (IS_NUMBER(x)) return x;
   if (IS_STRING(x)) return %StringToNumber(x);
   if (IS_BOOLEAN(x)) return x ? 1 : 0;
-  if (IS_UNDEFINED(x)) return %NumberNaN(1);
+  if (IS_UNDEFINED(x)) return %NumberNaN();
   return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x));
 };
 
index 21b7bd58d827c91117fb13e2a8414323758a9fb8..d1501e0e637c17b4eceb8eaa80c96b7c84c6d4bc 100644 (file)
@@ -1057,28 +1057,18 @@ Address Serializer::PutObject(HeapObject* obj) {
   writer_->PutInt(size >> kObjectAlignmentBits);
   PutEncodedAddress(addr);  // encodes AllocationSpace
 
-  // Get the map's encoded address, possibly serializing it on first
-  // visit. Note that we do not update obj->map(), since
-  // it already contains the forwarding address of 'obj'.
-  bool serialized;
-  Address map_addr = Encode(map, &serialized);
-
   // Visit all the pointers in the object other than the map. This
   // will recursively serialize any as-yet-unvisited objects.
-  obj->IterateBody(type, size, this);
+  obj->Iterate(this);
 
   // Mark end of recursively embedded objects, start of object body.
   writer_->PutC('|');
-  // Write out the encoded address for the map.
-  PutEncodedAddress(map_addr);
-
-  // Write out the raw contents of the object following the map
-  // pointer containing the now-updated pointers. No compression, but
+  // Write out the raw contents of the object. No compression, but
   // fast to deserialize.
+  writer_->PutBytes(obj->address(), size);
+  // Update pointers and external references in the written object.
   ReferenceUpdater updater(obj, this);
-  obj->IterateBody(type, size, &updater);
-  writer_->PutBytes(obj->address() + HeapObject::kSize,
-                    size - HeapObject::kSize);
+  obj->Iterate(&updater);
   updater.Update(writer_->position() - size);
 
 #ifdef DEBUG
@@ -1177,7 +1167,6 @@ void Deserializer::Deserialize() {
   GetHeader();
   Heap::IterateRoots(this);
   GetContextStack();
-  Heap::RebuildRSets();
 }
 
 
@@ -1364,16 +1353,9 @@ Object* Deserializer::GetObject() {
   }
   ASSERT(c == '|');
 
-  // Read, resolve and set the map pointer: don't rely on map being initialized.
-  Address map_addr = GetEncodedAddress();
-  Map* map = reinterpret_cast<Map*>(Resolve(map_addr));
   HeapObject* obj = reinterpret_cast<HeapObject*>(o);
-  obj->set_map(map);
-
   // Read the uninterpreted contents of the object after the map
-  reader_.GetBytes(obj->address() + HeapObject::kSize,
-                    size - HeapObject::kSize);
-
+  reader_.GetBytes(obj->address(), size);
 #ifdef DEBUG
   if (expect_debug_information_) {
     // Read in the epilogue to check that we're still synchronized
@@ -1382,7 +1364,9 @@ Object* Deserializer::GetObject() {
   }
 #endif
 
-  // Resolve the encoded pointers we just read in
+  // Resolve the encoded pointers we just read in.
+  // Same as obj->Iterate(this), but doesn't rely on the map pointer being set.
+  VisitPointer(reinterpret_cast<Object**>(obj->address()));
   obj->IterateBody(type, size, this);
 
   if (type == CODE_TYPE) {
index d3904110b1c03ffffcbbd29c87ce83edd6e34f22..59025954823e702ff56d17978d495472e115aa62 100644 (file)
@@ -34,7 +34,7 @@
 // Set the String function and constructor.
 %SetCode($String, function(x) {
   var value = %_ArgumentsLength() == 0 ? '' : ToString(x);
-  if (%IsConstructCall(this)) {
+  if (%IsConstructCall()) {
     %_SetValueOf(this, value);
   } else {
     return value;
@@ -349,7 +349,7 @@ function ApplyReplacementFunction(replace, captures, subject) {
   var pat = ToString(searchString);
   var index = (%_ArgumentsLength() > 1)
       ? ToNumber(%_Arguments(1) /* position */)
-      : %NumberNaN(1);
+      : %NumberNaN();
   var firstIndex;
   if ($isNaN(index)) {
     firstIndex = sub.length - pat.length;
index b553306a1c95e372fe5a2705e01b9037af7ea735..91d9140ec683d8898d905b577a25cb6970eac0cc 100644 (file)
@@ -160,7 +160,8 @@ Object* StubCompiler::CompileLazyCompile(Code::Flags flags) {
   __ EnterJSFrame(0);
 
   // Push the function on the stack and call the runtime function.
-  __ Push(MemOperand(pp, 0));
+  __ ldr(r0, MemOperand(pp, 0));
+  __ push(r0);
   __ CallRuntime(Runtime::kLazyCompile, 1);
 
   // Move result to r1 and restore number of arguments.
@@ -181,14 +182,16 @@ Object* CallStubCompiler::CompileCallField(Object* object,
                                            JSObject* holder,
                                            int index) {
   // ----------- S t a t e -------------
-  //  -- r0: number of arguments
-  //  -- r1: receiver
   //  -- lr: return address
   // -----------------------------------
 
   HandleScope scope;
   Label miss;
 
+  const int argc = arguments().immediate();
+
+  // Get the receiver of the function from the stack into r1.
+  __ ldr(r1, MemOperand(sp, argc * kPointerSize));
   // Check that the receiver isn't a smi.
   __ tst(r1, Operand(kSmiTagMask));
   __ b(eq, &miss);
@@ -211,9 +214,11 @@ Object* CallStubCompiler::CompileCallField(Object* object,
   __ 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.
-  __ add(ip, sp, Operand(r0, LSL, kPointerSizeLog2));
-  __ str(r3, MemOperand(ip, 1 * kPointerSize));
+  __ str(r3, 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));
@@ -237,13 +242,16 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
                                               JSFunction* function,
                                               CheckType check) {
   // ----------- S t a t e -------------
-  //  -- r1: receiver
   //  -- lr: return address
   // -----------------------------------
 
   HandleScope scope;
   Label miss;
 
+  // Get the receiver from the stack
+  const int argc = arguments().immediate();
+  __ ldr(r1, MemOperand(sp, argc * kPointerSize));
+
   // Check that the receiver isn't a smi.
   if (check != NUMBER_CHECK) {
     __ tst(r1, Operand(kSmiTagMask));
@@ -321,9 +329,6 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
       UNREACHABLE();
   }
 
-  // Number of arguments for this function.
-  const int argc = arguments().immediate();
-
   // Get the function and setup the context.
   __ mov(r3, Operand(Handle<JSFunction>(function)));
   __ ldr(cp, FieldMemOperand(r3, JSFunction::kContextOffset));
@@ -350,8 +355,6 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object,
                                                  JSObject* holder,
                                                  String* name) {
   // ----------- S t a t e -------------
-  //  -- r0: number of arguments
-  //  -- r1: receiver
   //  -- lr: return address
   // -----------------------------------
 
@@ -484,9 +487,10 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
   __ push(r2);  // name
   __ push(r0);  // value
 
-  // Do tail-call to the C builtin.
-  __ mov(r0, Operand(3));  // not counting receiver
-  __ JumpToBuiltin(ExternalReference(IC_Utility(IC::kStoreCallbackProperty)));
+  // Do tail-call to the runtime system.
+  ExternalReference store_callback_property =
+      ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
+  __ TailCallRuntime(store_callback_property, 4);
 
   // Handle store cache miss.
   __ bind(&miss);
@@ -537,11 +541,10 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
   __ push(r2);  // name
   __ push(r0);  // value
 
-  // Do tail-call to the C builtin.
-  __ mov(r0, Operand(2));  // not counting receiver
-  ExternalReference store_interceptor =
+  // Do tail-call to the runtime system.
+  ExternalReference store_ic_property =
       ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
-  __ JumpToBuiltin(store_interceptor);
+  __ TailCallRuntime(store_ic_property, 3);
 
   // Handle store cache miss.
   __ bind(&miss);
@@ -558,7 +561,6 @@ Object* LoadStubCompiler::CompileLoadField(JSObject* object,
                                            JSObject* holder,
                                            int index) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
@@ -567,6 +569,8 @@ Object* LoadStubCompiler::CompileLoadField(JSObject* object,
   HandleScope scope;
   Label miss;
 
+  __ ldr(r0, MemOperand(sp, 0));
+
   // Check that the receiver isn't a smi.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &miss);
@@ -597,7 +601,6 @@ Object* LoadStubCompiler::CompileLoadCallback(JSObject* object,
                                               JSObject* holder,
                                               AccessorInfo* callback) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
@@ -606,6 +609,7 @@ Object* LoadStubCompiler::CompileLoadCallback(JSObject* object,
   HandleScope scope;
   Label miss;
 
+  __ ldr(r0, MemOperand(sp, 0));
   // Check that the receiver isn't a smi.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &miss);
@@ -620,9 +624,10 @@ Object* LoadStubCompiler::CompileLoadCallback(JSObject* object,
   __ push(r2);  // name
   __ push(reg);  // holder
 
-  // Do tail-call to the C builtin.
-  __ mov(r0, Operand(3));  // not counting receiver
-  __ JumpToBuiltin(ExternalReference(IC_Utility(IC::kLoadCallbackProperty)));
+  // Do tail-call to the runtime system.
+  ExternalReference load_callback_property =
+      ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
+  __ TailCallRuntime(load_callback_property, 4);
 
   // Handle load cache miss.
   __ bind(&miss);
@@ -638,7 +643,6 @@ Object* LoadStubCompiler::CompileLoadConstant(JSObject* object,
                                               JSObject* holder,
                                               Object* value) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp] : receiver
@@ -647,6 +651,7 @@ Object* LoadStubCompiler::CompileLoadConstant(JSObject* object,
   HandleScope scope;
   Label miss;
 
+  __ ldr(r0, MemOperand(sp, 0));
   // Check that the receiver isn't a smi.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &miss);
@@ -672,7 +677,6 @@ Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object,
                                                  JSObject* holder,
                                                  String* name) {
   // ----------- S t a t e -------------
-  //  -- r0    : receiver
   //  -- r2    : name
   //  -- lr    : return address
   //  -- [sp]  : receiver
@@ -681,6 +685,7 @@ Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object,
   HandleScope scope;
   Label miss;
 
+  __ ldr(r0, MemOperand(sp, 0));
   // Check that the receiver isn't a smi.
   __ tst(r0, Operand(kSmiTagMask));
   __ b(eq, &miss);
@@ -693,9 +698,10 @@ Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object,
   __ push(reg);  // holder
   __ push(r2);  // name
 
-  // Do tail-call to the C builtin.
-  __ mov(r0, Operand(2));  // not counting receiver
-  __ JumpToBuiltin(ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)));
+  // Do tail-call to the runtime system.
+  ExternalReference load_ic_property =
+      ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
+  __ TailCallRuntime(load_ic_property, 3);
 
   // Handle load cache miss.
   __ bind(&miss);
index a0ef7d851485944e23e7662fafd07677e0c6681c..4c8416001b64bc540eeab661baf3c623b994be7e 100644 (file)
@@ -332,9 +332,10 @@ void StubCompiler::GenerateLoadCallback(MacroAssembler* masm,
   __ push(reg);  // holder
   __ push(scratch2);  // restore return address
 
-  // Do tail-call to the C builtin.
-  __ mov(eax, 3);  // not counting receiver
-  __ JumpToBuiltin(ExternalReference(IC_Utility(IC::kLoadCallbackProperty)));
+  // Do tail-call to the runtime system.
+  ExternalReference load_callback_property =
+      ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
+  __ TailCallRuntime(load_callback_property, 4);
 }
 
 
@@ -383,9 +384,10 @@ void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm,
   __ push(name);  // name
   __ push(scratch2);  // restore return address
 
-  // Do tail-call to the C builtin.
-  __ mov(eax, 2);  // not counting receiver
-  __ JumpToBuiltin(ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)));
+  // Do tail-call to the runtime system.
+  ExternalReference load_ic_property =
+      ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
+  __ TailCallRuntime(load_ic_property, 3);
 }
 
 
@@ -672,9 +674,9 @@ Object* CallStubCompiler::CompileCallInterceptor(Object* object,
   __ push(Operand(ebp, (argc + 3) * kPointerSize));  // name
 
   // Perform call.
-  __ mov(Operand(eax), Immediate(2));  // 2 arguments w/o receiver
   ExternalReference load_interceptor =
       ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
+  __ mov(Operand(eax), Immediate(3));
   __ mov(Operand(ebx), Immediate(load_interceptor));
 
   CEntryStub stub;
@@ -780,9 +782,10 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
   __ push(eax);  // value
   __ push(ebx);  // restore return address
 
-  // Do tail-call to the C builtin.
-  __ mov(eax, 3);  // not counting receiver
-  __ JumpToBuiltin(ExternalReference(IC_Utility(IC::kStoreCallbackProperty)));
+  // Do tail-call to the runtime system.
+  ExternalReference store_callback_property =
+      ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
+  __ TailCallRuntime(store_callback_property, 4);
 
   // Handle store cache miss.
   __ bind(&miss);
@@ -834,11 +837,10 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
   __ push(eax);  // value
   __ push(ebx);  // restore return address
 
-  // Do tail-call to the C builtin.
-  __ mov(eax, 2);  // not counting receiver
-  ExternalReference store_interceptor =
+  // Do tail-call to the runtime system.
+  ExternalReference store_ic_property =
       ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
-  __ JumpToBuiltin(store_interceptor);
+  __ TailCallRuntime(store_ic_property, 3);
 
   // Handle store cache miss.
   __ bind(&miss);
index f9bf02878b5bca0fdbf1c73c2de7c5fc801c3001..e7d5633e809b2eb37b3832f000712f135e9b6b85 100644 (file)
@@ -412,13 +412,13 @@ class StringBuilder {
   char* Finalize();
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
-
   char* buffer_;
   int size_;
   int position_;
 
   bool is_finalized() const { return position_ < 0; }
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
 };
 
 } }  // namespace v8::internal
index c56f5b76cae6735709ce04089ed61d3a756be387..8cacc690a8f976169caf9fda3825217e1809333e 100644 (file)
--- a/src/v8.h
+++ b/src/v8.h
 #ifndef V8_V8_H_
 #define V8_V8_H_
 
-// Google3 uses NDEBUG.
-#if defined(GOOGLE3) && !defined(NDEBUG)
-#define DEBUG
+#if defined(GOOGLE3)
+// Google3 special flag handling.
+#if defined(DEBUG) && defined(NDEBUG)
+// If both are defined in Google3, then we are building an optimized v8 with
+// assertions enabled.
+#undef NDEBUG
 #endif
+#endif  // defined(GOOGLE3)
 
 // V8 only uses DEBUG, but included external files
 // may use NDEBUG - make sure they are consistent.
index 6f1519bad4c834b5344bd16e8ac5c764fa721fbb..3755f74760047bb3e41fce6e4cd6481474965774 100644 (file)
@@ -33,7 +33,7 @@
 // const $Number = global.Number;
 // const $Function = global.Function;
 // const $Array = global.Array;
-// const $NaN = %NumberNaN(1);
+// const $NaN = %NumberNaN();
 
 
 // ECMA 262 - 15.1.1.1.
@@ -99,7 +99,7 @@ function $isFinite(number) {
 
 
 %SetCode($Boolean, function(x) {
-  if (%IsConstructCall(this)) {
+  if (%IsConstructCall()) {
     %_SetValueOf(this, ToBoolean(x));
   } else {
     return ToBoolean(x);
@@ -185,7 +185,7 @@ $Object.prototype.constructor = $Object;
 
 
 %SetCode($Object, function(x) {
-  if (%IsConstructCall(this)) {
+  if (%IsConstructCall()) {
     if (x == null) return this;
     return ToObject(x);
   } else {
@@ -245,7 +245,7 @@ $Object.prototype.constructor = $Object;
 // Set the Number function and constructor.
 %SetCode($Number, function(x) {
   var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x);
-  if (%IsConstructCall(this)) {
+  if (%IsConstructCall()) {
     %_SetValueOf(this, value);
   } else {
     return value;
@@ -257,10 +257,10 @@ $Object.prototype.constructor = $Object;
 %AddProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
 
 // ECMA-262 section 15.7.3.1.
-%AddProperty($Number, "MAX_VALUE", %NumberMaxValue(1), DONT_ENUM | DONT_DELETE | READ_ONLY);
+%AddProperty($Number, "MAX_VALUE", %NumberMaxValue(), DONT_ENUM | DONT_DELETE | READ_ONLY);
 
 // ECMA-262 section 15.7.3.2.
-%AddProperty($Number, "MIN_VALUE", %NumberMinValue(1), DONT_ENUM | DONT_DELETE | READ_ONLY);
+%AddProperty($Number, "MIN_VALUE", %NumberMinValue(), DONT_ENUM | DONT_DELETE | READ_ONLY);
 
 // ECMA-262 section 15.7.3.3.
 %AddProperty($Number, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
index 324b65005b05e461116f7a04e9b1e4e283f14bbd..996fb1407f676cf82b507a7c018452cc3bc141fe 100644 (file)
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 # Copyright 2006 Google Inc. All Rights Reserved.
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
@@ -336,9 +337,10 @@ def JS2C(source, target, env):
   output.close()
 
 def main():
-  output = sys.argv[1]
-  input = sys.argv[2:]
-  JS2C(input, [output], None)
+  natives = sys.argv[1]
+  natives_empty = sys.argv[2]
+  source_files = sys.argv[3:]
+  JS2C(source_files, [natives, natives_empty], None)
 
 if __name__ == "__main__":
   main()
diff --git a/tools/visual_studio/README.txt b/tools/visual_studio/README.txt
new file mode 100644 (file)
index 0000000..bd91b86
--- /dev/null
@@ -0,0 +1,51 @@
+This directory contains Microsoft Visual Studio project files for including v8
+in a Visual Studio solution.
+
+v8_base.vcproj
+--------------
+Base V8 library containing all the V8 code but no JavaScript library code. This
+includes third party code for regular expression handling (jscre) and
+string/number convertions (dtoa).
+
+v8.vcproj
+---------
+V8 library containing all the V8 and JavaScript library code embedded as source
+which is compiled as V8 is running.
+
+v8_mksnapshot.vcproj
+--------------------
+Executable v8_mksnapshot.exe for building a heap snapshot from a running V8.
+
+v8_snapshot.vcproj
+------------------
+V8 library containing all the V8 and JavaScript library code embedded as a heap
+snapshot instead of source to be compiled as V8 is running. Using this library
+provides significantly faster startup time than v8.vcproj.
+
+The property sheets common.vsprops, debug.vsprops and release.vsprops contains
+most of the configuration options and are inhireted by the project files
+described above. The location of the output directory used are defined in
+common.vsprops.
+
+With regard to Platform SDK version V8 has no specific requriments and builds
+with either what is supplied with Visual Studio 2005 or the latest Platform SDK
+from Microsoft.
+
+When adding these projects to a solution the following dependencies needs to be
+in place:
+
+  v8.vcproj depends on v8_base.vcproj
+  v8_mksnapshot.vcproj depends on v8.vcproj
+  v8_snapshot.vcproj depends on v8_mksnapshot.vcproj and v8_base.vcproj
+
+A project which uses V8 should then depend on v8_snapshot.vcproj.
+
+If V8 without snapshot if preferred only v8_base.vcproj and v8.vcproj are
+required and a project which uses V8 should depend on v8.vcproj.
+
+Python requirements
+-------------------
+When using the Microsoft Visual Studio project files Python version 2.4 or later
+is required. Make sure that python.exe is on the path before running Visual
+Studio. The use of Python is in the command script js2c.cmd which is used in the
+Custom Build Step for v8natives.js in the v8.vcproj project.
diff --git a/tools/visual_studio/common.vsprops b/tools/visual_studio/common.vsprops
new file mode 100644 (file)
index 0000000..ee8f591
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+       ProjectType="Visual C++"
+       Version="8.00"
+       Name="essential"
+       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+       IntermediateDirectory="$(SolutionDir)$(ConfigurationName)\obj\$(ProjectName)"
+       CharacterSet="1"
+       >
+       <Tool
+               Name="VCCLCompilerTool"
+               AdditionalIncludeDirectories="$(ProjectDir)\..\..\src;$(IntDir)\DerivedSources"
+               PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;_HAS_EXCEPTIONS=0;PCRE_STATIC;ENABLE_LOGGING_AND_PROFILING"
+               MinimalRebuild="false"
+               ExceptionHandling="0"
+               RuntimeTypeInfo="false"
+               WarningLevel="3"
+               WarnAsError="true"
+               Detect64BitPortabilityProblems="false"
+               DebugInformationFormat="3"
+               DisableSpecificWarnings="4355;4800"
+               BufferSecurityCheck="false"
+               EnableFunctionLevelLinking="true"
+       />
+       <Tool
+               Name="VCLibrarianTool"
+               OutputFile="$(OutDir)\lib\$(ProjectName).lib"
+       />
+       <Tool
+               Name="VCLinkerTool"
+               GenerateDebugInformation="true"
+               MapFileName="$(OutDir)\$(TargetName).map"
+               ImportLibrary="$(OutDir)\lib\$(TargetName).lib"
+               TargetMachine="1"
+               FixedBaseAddress="1"
+               AdditionalOptions="/IGNORE:4221 /NXCOMPAT"
+       />
+</VisualStudioPropertySheet>
diff --git a/tools/visual_studio/debug.vsprops b/tools/visual_studio/debug.vsprops
new file mode 100644 (file)
index 0000000..0abf924
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+       ProjectType="Visual C++"
+       Version="8.00"
+       Name="debug"
+       >
+       <Tool
+               Name="VCCLCompilerTool"
+               Optimization="0"
+               PreprocessorDefinitions="DEBUG;_DEBUG;ENABLE_DISASSEMBLER"
+               RuntimeLibrary="1"
+       />
+       <Tool
+               Name="VCLinkerTool"
+               LinkIncremental="2"
+       />
+</VisualStudioPropertySheet>
diff --git a/tools/visual_studio/js2c.cmd b/tools/visual_studio/js2c.cmd
new file mode 100644 (file)
index 0000000..10df45e
--- /dev/null
@@ -0,0 +1,6 @@
+@echo off
+set SOURCE_DIR=%1
+set TARGET_DIR=%2
+set PYTHON="..\..\..\third_party\python_24\python.exe"
+if not exist %PYTHON% set PYTHON=python.exe
+%PYTHON% ..\js2c.py %TARGET_DIR%\natives.cc %TARGET_DIR%\natives-empty.cc %SOURCE_DIR%\macros.py %SOURCE_DIR%\runtime.js %SOURCE_DIR%\v8natives.js %SOURCE_DIR%\array.js %SOURCE_DIR%\string.js %SOURCE_DIR%\uri.js %SOURCE_DIR%\math.js %SOURCE_DIR%\messages.js %SOURCE_DIR%\apinatives.js %SOURCE_DIR%\debug-delay.js %SOURCE_DIR%\mirror-delay.js %SOURCE_DIR%\date-delay.js %SOURCE_DIR%\regexp-delay.js
diff --git a/tools/visual_studio/release.vsprops b/tools/visual_studio/release.vsprops
new file mode 100644 (file)
index 0000000..311e7cf
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+       ProjectType="Visual C++"
+       Version="8.00"
+       Name="release"
+       >
+       <Tool
+               Name="VCCLCompilerTool"
+               RuntimeLibrary="0"
+               Optimization="3"
+               InlineFunctionExpansion="2"
+               EnableIntrinsicFunctions="true"
+               FavorSizeOrSpeed="0"
+               OmitFramePointers="true"
+       />
+       <Tool
+               Name="VCLinkerTool"
+               LinkIncremental="1"
+               OptimizeReferences="2"
+               OptimizeForWindows98="1"
+               EnableCOMDATFolding="2"
+       />
+</VisualStudioPropertySheet>
diff --git a/tools/visual_studio/v8.vcproj b/tools/visual_studio/v8.vcproj
new file mode 100644 (file)
index 0000000..d0b95a6
--- /dev/null
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8,00"
+       Name="v8"
+       ProjectGUID="{21E22961-22BF-4493-BD3A-868F93DA5179}"
+       RootNamespace="v8"
+       Keyword="Win32Proj"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       ConfigurationType="4"
+                       InheritedPropertySheets=".\common.vsprops;.\debug.vsprops"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               LinkLibraryDependencies="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       ConfigurationType="4"
+                       InheritedPropertySheets=".\common.vsprops;.\release.vsprops"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               LinkLibraryDependencies="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="js"
+                       >
+                       <File
+                               RelativePath="..\..\src\apinatives.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\array.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\date-delay.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\debug-delay.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\macros.py"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\math.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\messages.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\mirror-delay.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\regexp-delay.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\runtime.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\string.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\uri.js"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\v8natives.js"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Processing js files..."
+                                               CommandLine=".\js2c.cmd ..\..\src $(IntDir)\DerivedSources"
+                                               AdditionalDependencies="..\..\src\macros.py;..\..\src\runtime.js;..\..\src\v8natives.js;..\..\src\array.js;..\..\src\string.js;..\..\src\uri.js;..\..\src\math.js;..\..\src\messages.js;..\..\src\apinatives.js;..\..\src\debug-delay.js;..\..\src\mirror-delay.js;..\..\src\date-delay.js;..\..\src\regexp-delay.js"
+                                               Outputs="$(IntDir)\DerivedSources\natives.cc;$(IntDir)\DerivedSources\natives-empty.cc"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Processing js files..."
+                                               CommandLine=".\js2c.cmd ..\..\src $(IntDir)\DerivedSources"
+                                               AdditionalDependencies="..\..\src\macros.py;..\..\src\runtime.js;..\..\src\v8natives.js;..\..\src\array.js;..\..\src\string.js;..\..\src\uri.js;..\..\src\math.js;..\..\src\messages.js;..\..\src\apinatives.js;..\..\src\debug-delay.js;..\..\src\mirror-delay.js;..\..\src\date-delay.js;..\..\src\regexp-delay.js"
+                                               Outputs="$(IntDir)\DerivedSources\natives.cc;$(IntDir)\DerivedSources\natives-empty.cc"
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <Filter
+                       Name="generated files"
+                       >
+                       <File
+                               RelativePath="$(IntDir)\DerivedSources\natives.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\prebuild.py"
+                               >
+                       </File>
+               </Filter>
+               <File
+                       RelativePath="..\..\src\snapshot-empty.cc"
+                       >
+               </File>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/v8_base.vcproj b/tools/visual_studio/v8_base.vcproj
new file mode 100644 (file)
index 0000000..9541df0
--- /dev/null
@@ -0,0 +1,911 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8,00"
+       Name="v8_base"
+       ProjectGUID="{EC8B7909-62AF-470D-A75D-E1D89C837142}"
+       RootNamespace="v8_base"
+       Keyword="Win32Proj"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       ConfigurationType="4"
+                       InheritedPropertySheets=".\common.vsprops;.\debug.vsprops"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       ConfigurationType="4"
+                       InheritedPropertySheets=".\common.vsprops;.\release.vsprops"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="jscre"
+                       >
+                       <File
+                               RelativePath="..\..\src\third_party\jscre\pcre_compile.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UndefinePreprocessorDefinitions="DEBUG"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UndefinePreprocessorDefinitions="DEBUG"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\..\src\third_party\jscre\pcre_exec.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UndefinePreprocessorDefinitions="DEBUG"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UndefinePreprocessorDefinitions="DEBUG"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\..\src\third_party\jscre\pcre_internal.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\third_party\jscre\pcre_tables.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UndefinePreprocessorDefinitions="DEBUG"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UndefinePreprocessorDefinitions="DEBUG"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\..\src\third_party\jscre\pcre_ucp_searchfuncs.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UndefinePreprocessorDefinitions="DEBUG"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UndefinePreprocessorDefinitions="DEBUG"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\..\src\third_party\jscre\pcre_xclass.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UndefinePreprocessorDefinitions="DEBUG"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UndefinePreprocessorDefinitions="DEBUG"
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <Filter
+                       Name="dtoa"
+                       >
+                       <File
+                               RelativePath="..\..\src\dtoa-config.c"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               DisableSpecificWarnings="4018;4244"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               DisableSpecificWarnings="4018;4244"
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <Filter
+                       Name="src"
+                       >
+                       <File
+                               RelativePath="..\..\src\accessors.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\accessors.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\allocation.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\allocation.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\api.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\api.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\arguments.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\assembler-arm-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\assembler-arm.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\assembler-ia32-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\assembler-ia32.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\assembler-ia32.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\assembler.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\ast.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\ast.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\bootstrapper.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\bootstrapper.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\builtins-ia32.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\builtins.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\builtins.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\char-predicates-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\char-predicates.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\checks.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\checks.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\code-stubs.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\code-stubs.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\code.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\codegen-ia32.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\codegen-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\codegen.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\codegen.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\compiler.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\compiler.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\contexts.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\contexts.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\conversions-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\conversions.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\conversions.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\counters.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\counters.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\cpu-ia32.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\cpu.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\dateparser.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\dateparser.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\debug.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\debug.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\disassembler.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\disassembler.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\execution.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\execution.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\factory.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\factory.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\flags.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\flags.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\frames-arm-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\frames-arm.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\frames-ia32-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\frames-ia32.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\frames-ia32.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\frames-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\frames.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\frames.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\global-handles.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\global-handles.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\globals.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\handles-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\handles.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\handles.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\hashmap.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\hashmap.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\heap-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\heap.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\heap.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\ic-ia32.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\ic-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\ic.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\ic.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\interceptors.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\jsregexp.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\jsregexp.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\list-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\list.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\log.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\log.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\macro-assembler-arm.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\macro-assembler-ia32.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\macro-assembler-ia32.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\macro-assembler.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\mark-compact.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\mark-compact.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\memory.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\messages.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\messages.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\natives.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\objects-debug.cc"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       ExcludedFromBuild="true"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\..\src\objects-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\objects.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\objects.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\parser.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\parser.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\platform-win32.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\platform.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\prettyprinter.cc"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       ExcludedFromBuild="true"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\..\src\prettyprinter.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\property.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\property.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\rewriter.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\rewriter.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\runtime.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\runtime.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\scanner.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\scanner.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\scopeinfo.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\scopeinfo.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\scopes.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\scopes.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\serialize.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\serialize.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\shell.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\snapshot-common.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\snapshot.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\spaces-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\spaces.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\spaces.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\string-stream.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\string-stream.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\stub-cache-ia32.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\stub-cache.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\stub-cache.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\token.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\token.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\top.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\top.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\unicode-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\unicode.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\usage-analyzer.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\usage-analyzer.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\utils.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\utils.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\v8-counters.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\v8-counters.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\v8.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\v8.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\v8threads.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\v8threads.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\variables.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\variables.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\zone-inl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\zone.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\zone.h"
+                               >
+                       </File>
+                       <Filter
+                               Name="third party"
+                               >
+                               <File
+                                       RelativePath="..\..\src\disasm-ia32.cc"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\src\disasm.h"
+                                       >
+                               </File>
+                       </Filter>
+                       <Filter
+                               Name="generated files"
+                               >
+                               <File
+                                       RelativePath="..\..\src\unicode.cc"
+                                       >
+                               </File>
+                       </Filter>
+               </Filter>
+               <Filter
+                       Name="public"
+                       >
+                       <File
+                               RelativePath="..\public\debug.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\public\v8.h"
+                               >
+                       </File>
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/v8_mksnapshot.vcproj b/tools/visual_studio/v8_mksnapshot.vcproj
new file mode 100644 (file)
index 0000000..ad78d94
--- /dev/null
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8,00"
+       Name="v8_mksnapshot"
+       ProjectGUID="{865575D0-37E2-405E-8CBA-5F6C485B5A26}"
+       RootNamespace="v8_mksnapshot"
+       Keyword="Win32Proj"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       ConfigurationType="1"
+                       InheritedPropertySheets=".\common.vsprops;.\debug.vsprops"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCWebDeploymentTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       ConfigurationType="1"
+                       InheritedPropertySheets=".\common.vsprops;.\release.vsprops"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCWebDeploymentTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <File
+                       RelativePath="..\..\src\mksnapshot.cc"
+                       >
+               </File>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/v8_snapshot.vcproj b/tools/visual_studio/v8_snapshot.vcproj
new file mode 100644 (file)
index 0000000..eb9c9c2
--- /dev/null
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8,00"
+       Name="v8_snapshot"
+       ProjectGUID="{C0334F9A-1168-4101-9DD8-C30FB252D435}"
+       RootNamespace="v8_snapshot"
+       Keyword="Win32Proj"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       ConfigurationType="4"
+                       InheritedPropertySheets=".\common.vsprops;.\debug.vsprops"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               LinkLibraryDependencies="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       ConfigurationType="4"
+                       InheritedPropertySheets=".\common.vsprops;.\release.vsprops"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               LinkLibraryDependencies="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="generated files"
+                       >
+                       <File
+                               RelativePath="$(IntDir)\..\v8\DerivedSources\natives-empty.cc"
+                               >
+                       </File>
+                       <File
+                               RelativePath="$(IntDir)\DerivedSources\snapshot.cc"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories="$(SolutionDir)..\v8\src"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories="$(SolutionDir)..\v8\src"
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <File
+                       RelativePath="$(OutDir)\mksnapshot.exe"
+                       >
+                       <FileConfiguration
+                               Name="Debug|Win32"
+                               >
+                               <Tool
+                                       Name="VCCustomBuildTool"
+                                       Description="Building snapshot..."
+                                       CommandLine="$(OutDir)\v8_mksnapshot.exe $(IntDir)\DerivedSources\snapshot.cc"
+                                       Outputs="$(IntDir)\DerivedSources\snapshot.cc"
+                               />
+                       </FileConfiguration>
+                       <FileConfiguration
+                               Name="Release|Win32"
+                               >
+                               <Tool
+                                       Name="VCCustomBuildTool"
+                                       Description="Building snapshot..."
+                                       CommandLine="$(OutDir)\v8_mksnapshot.exe $(IntDir)\DerivedSources\snapshot.cc"
+                                       Outputs="$(IntDir)\DerivedSources\snapshot.cc"
+                               />
+                       </FileConfiguration>
+               </File>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>