Push version 1.3.17 to trunk.

Added API method to get simple heap statistics.

Improved heap profiler support.

Fixed the implementation of the resource constraint API so it works when using snapshots.

Fixed a number of issues in the Windows 64-bit version.

Optimized calls to API getters.

Added valgrind notification on code modification to the 64-bit version.

Fixed issue where we logged shared library addresses on Windows at startup and never used them.



git-svn-id: http://v8.googlecode.com/svn/trunk@3167 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index a3b2149..34d4fd5 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -319,11 +319,17 @@
 
 
 void MacroAssembler::FCmp() {
-  fucompp();
-  push(eax);
-  fnstsw_ax();
-  sahf();
-  pop(eax);
+  if (CpuFeatures::IsSupported(CpuFeatures::CMOV)) {
+    fucomip();
+    ffree(0);
+    fincstp();
+  } else {
+    fucompp();
+    push(eax);
+    fnstsw_ax();
+    sahf();
+    pop(eax);
+  }
 }
 
 
@@ -349,10 +355,7 @@
   leave();
 }
 
-
-void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
-  ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG);
-
+void MacroAssembler::EnterExitFramePrologue(ExitFrame::Mode mode) {
   // Setup the frame structure on the stack.
   ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize);
   ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize);
@@ -363,23 +366,24 @@
   // Reserve room for entry stack pointer and push the debug marker.
   ASSERT(ExitFrameConstants::kSPOffset  == -1 * kPointerSize);
   push(Immediate(0));  // saved entry sp, patched before call
-  push(Immediate(type == StackFrame::EXIT_DEBUG ? 1 : 0));
+  if (mode == ExitFrame::MODE_DEBUG) {
+    push(Immediate(0));
+  } else {
+    push(Immediate(CodeObject()));
+  }
 
   // Save the frame pointer and the context in top.
   ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
   ExternalReference context_address(Top::k_context_address);
   mov(Operand::StaticVariable(c_entry_fp_address), ebp);
   mov(Operand::StaticVariable(context_address), esi);
+}
 
-  // Setup argc and argv in callee-saved registers.
-  int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
-  mov(edi, Operand(eax));
-  lea(esi, Operand(ebp, eax, times_4, offset));
-
+void MacroAssembler::EnterExitFrameEpilogue(ExitFrame::Mode mode, int argc) {
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // Save the state of all registers to the stack from the memory
   // location. This is needed to allow nested break points.
-  if (type == StackFrame::EXIT_DEBUG) {
+  if (mode == ExitFrame::MODE_DEBUG) {
     // TODO(1243899): This should be symmetric to
     // CopyRegistersFromStackToMemory() but it isn't! esp is assumed
     // correct here, but computed for the other call. Very error
@@ -390,8 +394,8 @@
   }
 #endif
 
-  // Reserve space for two arguments: argc and argv.
-  sub(Operand(esp), Immediate(2 * kPointerSize));
+  // Reserve space for arguments.
+  sub(Operand(esp), Immediate(argc * kPointerSize));
 
   // Get the required frame alignment for the OS.
   static const int kFrameAlignment = OS::ActivationFrameAlignment();
@@ -405,15 +409,39 @@
 }
 
 
-void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
+void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode) {
+  EnterExitFramePrologue(mode);
+
+  // Setup argc and argv in callee-saved registers.
+  int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
+  mov(edi, Operand(eax));
+  lea(esi, Operand(ebp, eax, times_4, offset));
+
+  EnterExitFrameEpilogue(mode, 2);
+}
+
+
+void MacroAssembler::EnterApiExitFrame(ExitFrame::Mode mode,
+                                       int stack_space,
+                                       int argc) {
+  EnterExitFramePrologue(mode);
+
+  int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
+  lea(esi, Operand(ebp, (stack_space * kPointerSize) + offset));
+
+  EnterExitFrameEpilogue(mode, argc);
+}
+
+
+void MacroAssembler::LeaveExitFrame(ExitFrame::Mode mode) {
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // Restore the memory copy of the registers by digging them out from
   // the stack. This is needed to allow nested break points.
-  if (type == StackFrame::EXIT_DEBUG) {
+  if (mode == ExitFrame::MODE_DEBUG) {
     // It's okay to clobber register ebx below because we don't need
     // the function pointer after this.
     const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize;
-    int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize;
+    int kOffset = ExitFrameConstants::kCodeOffset - kCallerSavedSize;
     lea(ebx, Operand(ebp, kOffset));
     CopyRegistersFromStackToMemory(ebx, ecx, kJSCallerSaved);
   }
@@ -767,6 +795,24 @@
 }
 
 
+void MacroAssembler::AllocateHeapNumber(Register result,
+                                        Register scratch1,
+                                        Register scratch2,
+                                        Label* gc_required) {
+  // Allocate heap number in new space.
+  AllocateInNewSpace(HeapNumber::kSize,
+                     result,
+                     scratch1,
+                     scratch2,
+                     gc_required,
+                     TAG_OBJECT);
+
+  // Set the map.
+  mov(FieldOperand(result, HeapObject::kMapOffset),
+      Immediate(Factory::heap_number_map()));
+}
+
+
 void MacroAssembler::NegativeZeroTest(CodeGenerator* cgen,
                                       Register result,
                                       Register op,
@@ -907,6 +953,48 @@
 }
 
 
+void MacroAssembler::PushHandleScope(Register scratch) {
+  // Push the number of extensions, smi-tagged so the gc will ignore it.
+  ExternalReference extensions_address =
+      ExternalReference::handle_scope_extensions_address();
+  mov(scratch, Operand::StaticVariable(extensions_address));
+  ASSERT_EQ(0, kSmiTag);
+  shl(scratch, kSmiTagSize);
+  push(scratch);
+  mov(Operand::StaticVariable(extensions_address), Immediate(0));
+  // Push next and limit pointers which will be wordsize aligned and
+  // hence automatically smi tagged.
+  ExternalReference next_address =
+      ExternalReference::handle_scope_next_address();
+  push(Operand::StaticVariable(next_address));
+  ExternalReference limit_address =
+      ExternalReference::handle_scope_limit_address();
+  push(Operand::StaticVariable(limit_address));
+}
+
+
+void MacroAssembler::PopHandleScope(Register scratch) {
+  ExternalReference extensions_address =
+        ExternalReference::handle_scope_extensions_address();
+  Label write_back;
+  mov(scratch, Operand::StaticVariable(extensions_address));
+  cmp(Operand(scratch), Immediate(0));
+  j(equal, &write_back);
+  CallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
+
+  bind(&write_back);
+  ExternalReference limit_address =
+        ExternalReference::handle_scope_limit_address();
+  pop(Operand::StaticVariable(limit_address));
+  ExternalReference next_address =
+        ExternalReference::handle_scope_next_address();
+  pop(Operand::StaticVariable(next_address));
+  pop(scratch);
+  shr(scratch, kSmiTagSize);
+  mov(Operand::StaticVariable(extensions_address), scratch);
+}
+
+
 void MacroAssembler::JumpToRuntime(const ExternalReference& ext) {
   // Set the entry point and jump to the C entry runtime stub.
   mov(ebx, Immediate(ext));