Version 1.2.12.

Added stack traces collection to Error objects accessible through the e.stack property.

Changed RegExp parser to use a recursive data structure instead of stack-based recursion.

Optimized Date object construction and string concatenation.

Improved performance of div, mod, and mul on ARM platforms.


git-svn-id: http://v8.googlecode.com/svn/trunk@2361 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 780fcdb..1a0b119 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -399,6 +399,51 @@
 }
 
 
+void MacroAssembler::TryGetFunctionPrototype(Register function,
+                                             Register result,
+                                             Label* miss) {
+  // Check that the receiver isn't a smi.
+  testl(function, Immediate(kSmiTagMask));
+  j(zero, miss);
+
+  // Check that the function really is a function.
+  CmpObjectType(function, JS_FUNCTION_TYPE, result);
+  j(not_equal, miss);
+
+  // Make sure that the function has an instance prototype.
+  Label non_instance;
+  testb(FieldOperand(result, Map::kBitFieldOffset),
+        Immediate(1 << Map::kHasNonInstancePrototype));
+  j(not_zero, &non_instance);
+
+  // Get the prototype or initial map from the function.
+  movq(result,
+       FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
+
+  // If the prototype or initial map is the hole, don't return it and
+  // simply miss the cache instead. This will allow us to allocate a
+  // prototype object on-demand in the runtime system.
+  Cmp(result, Factory::the_hole_value());
+  j(equal, miss);
+
+  // If the function does not have an initial map, we're done.
+  Label done;
+  CmpObjectType(result, MAP_TYPE, kScratchRegister);
+  j(not_equal, &done);
+
+  // Get the prototype from the initial map.
+  movq(result, FieldOperand(result, Map::kPrototypeOffset));
+  jmp(&done);
+
+  // Non-instance prototype: Fetch prototype from constructor field
+  // in initial map.
+  bind(&non_instance);
+  movq(result, FieldOperand(result, Map::kConstructorOffset));
+
+  // All done.
+  bind(&done);
+}
+
 
 void MacroAssembler::SetCounter(StatsCounter* counter, int value) {
   if (FLAG_native_code_counters && counter->Enabled()) {
@@ -704,6 +749,7 @@
   ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG);
 
   // Setup the frame structure on the stack.
+  // All constants are relative to the frame pointer of the exit frame.
   ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize);
   ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize);
   ASSERT(ExitFrameConstants::kCallerFPOffset ==  0 * kPointerSize);
@@ -718,7 +764,7 @@
   // 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);
-  movq(rdi, rax);  // Backup rax before we use it.
+  movq(r14, rax);  // Backup rax before we use it.
 
   movq(rax, rbp);
   store_rax(c_entry_fp_address);
@@ -728,7 +774,7 @@
   // Setup argv in callee-saved register r15. It is reused in LeaveExitFrame,
   // so it must be retained across the C-call.
   int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
-  lea(r15, Operand(rbp, rdi, times_pointer_size, offset));
+  lea(r15, Operand(rbp, r14, times_pointer_size, offset));
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // Save the state of all registers to the stack from the memory