Changed all text files to have native svn:eol-style.

Added a few samples and support for building them. The samples include a simple shell that can be used to benchmark and test V8.

Changed V8::GetVersion to return the version as a string.

Added source for lazily loaded scripts to snapshots and made serialization non-destructive.

Improved ARM support by fixing the write barrier code to use aligned loads and stores and by removing premature locals optimization that relied on broken support for callee-saved registers (removed).

Refactored the code for marking live objects during garbage collection and the code for allocating objects in paged spaces. Introduced an abstraction for the map word of a heap-allocated object and changed the memory allocator to allocate executable memory only for spaces that may contain code objects.

Moved StringBuilder to utils.h and ScopedLock to platform.h, where they can be used by debugging and logging modules. Added thread-safe message queues for dealing with debugger events.

Fixed the source code reported by toString for certain builtin empty functions and made sure that the prototype property of a function is enumerable.

Improved performance of converting values to condition flags in generated code.

Merged disassembler-{arch} files.


git-svn-id: http://v8.googlecode.com/svn/trunk@8 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/macro-assembler-arm.cc b/src/macro-assembler-arm.cc
index a241041..16003c0 100644
--- a/src/macro-assembler-arm.cc
+++ b/src/macro-assembler-arm.cc
@@ -46,7 +46,8 @@
 MacroAssembler::MacroAssembler(void* buffer, int size)
     : Assembler(buffer, size),
       unresolved_(0),
-      generating_stub_(false) {
+      generating_stub_(false),
+      allow_stub_calls_(true) {
 }
 
 
@@ -209,23 +210,31 @@
 
   Label fast, done;
 
-  // First, test that the start address is not in the new space.  We cannot
-  // set remembered set bits in the new space.
+  // First, test that the object is not in the new space.  We cannot set
+  // remembered set bits in the new space.
+  // object: heap object pointer (with tag)
+  // offset: offset to store location from the object
   and_(scratch, object, Operand(Heap::NewSpaceMask()));
   cmp(scratch, Operand(ExternalReference::new_space_start()));
   b(eq, &done);
 
-  mov(ip, Operand(Page::kPageAlignmentMask));  // load mask only once
   // Compute the bit offset in the remembered set.
-  and_(scratch, object, Operand(ip));
-  add(offset, scratch, Operand(offset));
+  // object: heap object pointer (with tag)
+  // offset: offset to store location from the object
+  mov(ip, Operand(Page::kPageAlignmentMask));  // load mask only once
+  and_(scratch, object, Operand(ip));  // offset into page of the object
+  add(offset, scratch, Operand(offset));  // add offset into the object
   mov(offset, Operand(offset, LSR, kObjectAlignmentBits));
 
   // Compute the page address from the heap object pointer.
+  // object: heap object pointer (with tag)
+  // offset: bit offset of store position in the remembered set
   bic(object, object, Operand(ip));
 
   // If the bit offset lies beyond the normal remembered set range, it is in
   // the extra remembered set area of a large object.
+  // object: page start
+  // offset: bit offset of store position in the remembered set
   cmp(offset, Operand(Page::kPageSize / kPointerSize));
   b(lt, &fast);
 
@@ -245,11 +254,14 @@
   add(object, object, Operand(scratch));
 
   bind(&fast);
-  // Now object is the address of the start of the remembered set and offset
-  // is the bit offset from that start.
   // Get address of the rset word.
-  add(object, object, Operand(offset, LSR, kRSetWordShift));
-  // Get bit offset in the word.
+  // object: start of the remembered set (page start for the fast case)
+  // offset: bit offset of store position in the remembered set
+  bic(scratch, offset, Operand(kBitsPerInt - 1));  // clear the bit offset
+  add(object, object, Operand(scratch, LSR, kRSetWordShift));
+  // Get bit offset in the rset word.
+  // object: address of remembered set word
+  // offset: bit offset of store position
   and_(offset, offset, Operand(kBitsPerInt - 1));
 
   ldr(scratch, MemOperand(object));
@@ -261,7 +273,7 @@
 }
 
 
-void MacroAssembler::EnterJSFrame(int argc, RegList callee_saved) {
+void MacroAssembler::EnterJSFrame(int argc) {
   // Generate code entering a JS function called from a JS function
   // stack: receiver, arguments
   // r0: number of arguments (not including function, nor receiver)
@@ -299,18 +311,10 @@
   mov(r3, Operand(r0));  // args_len to be saved
   mov(r2, Operand(cp));  // context to be saved
 
-  // Make sure there are no instructions between both stm instructions, because
-  // the callee_saved list is obtained during stack unwinding by decoding the
-  // first stmdb instruction, which is found (or not) at a constant offset from
-  // the pc saved by the second stmdb instruction.
-  if (callee_saved != 0) {
-    stm(db_w, sp, callee_saved);
-  }
-
   // push in reverse order: context (r2), args_len (r3), caller_pp, caller_fp,
-  // sp_on_exit (ip == pp, may be patched on exit), return address, prolog_pc
+  // sp_on_exit (ip == pp, may be patched on exit), return address
   stm(db_w, sp, r2.bit() | r3.bit() | pp.bit() | fp.bit() |
-      ip.bit() | lr.bit() | pc.bit());
+      ip.bit() | lr.bit());
 
   // Setup new frame pointer.
   add(fp, sp, Operand(-StandardFrameConstants::kContextOffset));
@@ -321,20 +325,16 @@
 }
 
 
-void MacroAssembler::ExitJSFrame(ExitJSFlag flag, RegList callee_saved) {
+void MacroAssembler::ExitJSFrame(ExitJSFlag flag) {
   // r0: result
   // sp: stack pointer
   // fp: frame pointer
   // pp: parameter pointer
 
-  if (callee_saved != 0 || flag == DO_NOT_RETURN) {
+  if (flag == DO_NOT_RETURN) {
     add(r3, fp, Operand(JavaScriptFrameConstants::kSavedRegistersOffset));
   }
 
-  if (callee_saved != 0) {
-    ldm(ia_w, r3, callee_saved);
-  }
-
   if (flag == DO_NOT_RETURN) {
     // restore sp as caller_sp (not as pp)
     str(r3, MemOperand(fp, JavaScriptFrameConstants::kSPOnExitOffset));
@@ -563,13 +563,13 @@
 
 
 void MacroAssembler::CallStub(CodeStub* stub) {
-  ASSERT(!generating_stub());  // stub calls are not allowed in stubs
+  ASSERT(allow_stub_calls());  // stub calls are not allowed in some stubs
   Call(stub->GetCode(), code_target);
 }
 
 
 void MacroAssembler::CallJSExitStub(CodeStub* stub) {
-  ASSERT(!generating_stub());  // stub calls are not allowed in stubs
+  ASSERT(allow_stub_calls());  // stub calls are not allowed in some stubs
   Call(stub->GetCode(), exit_js_frame);
 }
 
@@ -592,6 +592,15 @@
     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
   }
 
   RuntimeStub stub((Runtime::FunctionId) f->stub_id);
@@ -605,16 +614,6 @@
 
 
 void MacroAssembler::TailCallRuntime(Runtime::Function* f) {
-  // 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 fixed for this call.
-    // Set r0 correspondingly.
-    push(r0);
-    mov(r0, Operand(f->nargs - 1));  // receiver does not count as an argument
-  }
   JumpToBuiltin(ExternalReference(f));  // tail call to runtime routine
 }