Upgrade v8 to 1.3.10
authorRyan <ry@tinyclouds.org>
Wed, 9 Sep 2009 20:01:54 +0000 (22:01 +0200)
committerRyan <ry@tinyclouds.org>
Wed, 9 Sep 2009 20:01:54 +0000 (22:01 +0200)
97 files changed:
deps/v8/AUTHORS
deps/v8/ChangeLog
deps/v8/SConstruct
deps/v8/include/v8.h
deps/v8/src/SConscript
deps/v8/src/api.cc
deps/v8/src/api.h
deps/v8/src/arm/builtins-arm.cc
deps/v8/src/arm/codegen-arm.cc
deps/v8/src/arm/constants-arm.cc [new file with mode: 0644]
deps/v8/src/arm/constants-arm.h
deps/v8/src/arm/debug-arm.cc
deps/v8/src/arm/disasm-arm.cc
deps/v8/src/arm/ic-arm.cc
deps/v8/src/arm/macro-assembler-arm.cc
deps/v8/src/arm/macro-assembler-arm.h
deps/v8/src/arm/regexp-macro-assembler-arm.cc
deps/v8/src/arm/simulator-arm.cc
deps/v8/src/arm/stub-cache-arm.cc
deps/v8/src/bootstrapper.cc
deps/v8/src/builtins.cc
deps/v8/src/builtins.h
deps/v8/src/checks.h
deps/v8/src/codegen.cc
deps/v8/src/codegen.h
deps/v8/src/d8.cc
deps/v8/src/d8.js
deps/v8/src/debug.cc
deps/v8/src/debug.h
deps/v8/src/heap.cc
deps/v8/src/ia32/builtins-ia32.cc
deps/v8/src/ia32/codegen-ia32.cc
deps/v8/src/ia32/debug-ia32.cc
deps/v8/src/ia32/ic-ia32.cc
deps/v8/src/ia32/macro-assembler-ia32.cc
deps/v8/src/ia32/macro-assembler-ia32.h
deps/v8/src/ia32/stub-cache-ia32.cc
deps/v8/src/list.h
deps/v8/src/log.cc
deps/v8/src/macro-assembler.h
deps/v8/src/mark-compact.cc
deps/v8/src/mark-compact.h
deps/v8/src/mirror-delay.js
deps/v8/src/objects-debug.cc
deps/v8/src/objects.cc
deps/v8/src/objects.h
deps/v8/src/platform-freebsd.cc
deps/v8/src/platform-linux.cc
deps/v8/src/platform-macos.cc
deps/v8/src/runtime.cc
deps/v8/src/runtime.h
deps/v8/src/serialize.cc
deps/v8/src/serialize.h
deps/v8/src/spaces.cc
deps/v8/src/spaces.h
deps/v8/src/v8threads.cc
deps/v8/src/v8threads.h
deps/v8/src/version.cc
deps/v8/src/x64/assembler-x64.cc
deps/v8/src/x64/builtins-x64.cc
deps/v8/src/x64/codegen-x64.cc
deps/v8/src/x64/debug-x64.cc
deps/v8/src/x64/ic-x64.cc
deps/v8/src/x64/macro-assembler-x64.cc
deps/v8/src/x64/macro-assembler-x64.h
deps/v8/src/x64/regexp-macro-assembler-x64.cc
deps/v8/src/x64/regexp-macro-assembler-x64.h
deps/v8/src/x64/stub-cache-x64.cc
deps/v8/test/cctest/cctest.status
deps/v8/test/cctest/test-assembler-arm.cc
deps/v8/test/cctest/test-debug.cc
deps/v8/test/cctest/test-log.cc
deps/v8/test/cctest/testcfg.py
deps/v8/test/mjsunit/debug-scopes.js
deps/v8/test/mjsunit/debug-step-stub-callfunction.js
deps/v8/test/mjsunit/debug-stepin-call-function-stub.js [new file with mode: 0644]
deps/v8/test/mjsunit/debug-stepout-recursive-function.js [new file with mode: 0644]
deps/v8/test/mjsunit/debug-stepout-to-builtin.js [new file with mode: 0644]
deps/v8/test/mjsunit/function-prototype.js
deps/v8/test/mjsunit/mjsunit.status
deps/v8/test/mjsunit/regress/regress-246.js [changed mode: 0755->0644]
deps/v8/test/mjsunit/regress/regress-254.js [changed mode: 0755->0644]
deps/v8/test/mjsunit/regress/regress-crbug-18639.js [new file with mode: 0644]
deps/v8/test/mjsunit/testcfg.py
deps/v8/test/mozilla/mozilla.status
deps/v8/tools/tickprocessor.js
deps/v8/tools/visual_studio/arm.vsprops
deps/v8/tools/visual_studio/common.vsprops
deps/v8/tools/visual_studio/d8_arm.vcproj [new file with mode: 0644]
deps/v8/tools/visual_studio/ia32.vsprops
deps/v8/tools/visual_studio/v8_arm.sln
deps/v8/tools/visual_studio/v8_arm.vcproj [new file with mode: 0644]
deps/v8/tools/visual_studio/v8_base_arm.vcproj
deps/v8/tools/visual_studio/v8_cctest_arm.vcproj
deps/v8/tools/visual_studio/v8_process_sample_arm.vcproj [new file with mode: 0644]
deps/v8/tools/visual_studio/v8_shell_sample_arm.vcproj [new file with mode: 0644]
deps/v8/tools/visual_studio/x64.vsprops

index bfe58a2..5c5ae4e 100644 (file)
@@ -17,3 +17,4 @@ Paolo Giarrusso <p.giarrusso@gmail.com>
 Rafal Krypa <rafal@krypa.net>
 Rene Rebe <rene@exactcode.de>
 Ryan Dahl <coldredlemur@gmail.com>
+Patrick Gansterer <paroga@paroga.com>
index b07e7cc..a78755b 100644 (file)
@@ -1,3 +1,15 @@
+2009-09-09: Version 1.3.10
+
+        Fixed profiler on Mac in 64-bit mode.
+
+        Optimized creation of objects from simple constructor functions on
+        ARM.
+
+        Fixed a number of debugger issues.
+
+        Reduced the amount of memory consumed by V8.
+
+
 2009-09-02: Version 1.3.9
 
         Optimized stack guard checks on ARM.
index 71673c0..ddd0190 100644 (file)
@@ -258,6 +258,10 @@ V8_EXTRA_FLAGS = {
     'all': {
       'WARNINGFLAGS': ['/WX', '/wd4355', '/wd4800']
     },
+    'library:shared': {
+      'CPPDEFINES': ['BUILDING_V8_SHARED'],
+      'LIBS': ['winmm', 'ws2_32']
+    },
     'arch:ia32': {
       'WARNINGFLAGS': ['/W3']
     },
index 346050d..2789bad 100644 (file)
@@ -979,8 +979,9 @@ class V8EXPORT String : public Primitive {
    public:
     explicit Utf8Value(Handle<v8::Value> obj);
     ~Utf8Value();
-    char* operator*() const { return str_; }
-    int length() { return length_; }
+    char* operator*() { return str_; }
+    const char* operator*() const { return str_; }
+    int length() const { return length_; }
    private:
     char* str_;
     int length_;
@@ -1001,8 +1002,9 @@ class V8EXPORT String : public Primitive {
    public:
     explicit AsciiValue(Handle<v8::Value> obj);
     ~AsciiValue();
-    char* operator*() const { return str_; }
-    int length() { return length_; }
+    char* operator*() { return str_; }
+    const char* operator*() const { return str_; }
+    int length() const { return length_; }
    private:
     char* str_;
     int length_;
@@ -1022,8 +1024,9 @@ class V8EXPORT String : public Primitive {
    public:
     explicit Value(Handle<v8::Value> obj);
     ~Value();
-    uint16_t* operator*() const { return str_; }
-    int length() { return length_; }
+    uint16_t* operator*() { return str_; }
+    const uint16_t* operator*() const { return str_; }
+    int length() const { return length_; }
    private:
     uint16_t* str_;
     int length_;
index fee3fab..a1cbf1b 100755 (executable)
@@ -56,9 +56,9 @@ SOURCES = {
   ],
   'arch:arm': [
     'arm/assembler-arm.cc', 'arm/builtins-arm.cc', 'arm/cfg-arm.cc',
-    'arm/codegen-arm.cc', 'arm/cpu-arm.cc', 'arm/disasm-arm.cc',
-    'arm/debug-arm.cc', 'arm/frames-arm.cc', 'arm/ic-arm.cc',
-    'arm/jump-target-arm.cc', 'arm/macro-assembler-arm.cc',
+    'arm/codegen-arm.cc', 'arm/constants-arm.cc', 'arm/cpu-arm.cc',
+    'arm/disasm-arm.cc', 'arm/debug-arm.cc', 'arm/frames-arm.cc',
+    'arm/ic-arm.cc', 'arm/jump-target-arm.cc', 'arm/macro-assembler-arm.cc',
     'arm/regexp-macro-assembler-arm.cc',
     'arm/register-allocator-arm.cc', 'arm/stub-cache-arm.cc',
     'arm/virtual-frame-arm.cc'
index 679e038..1128d3e 100644 (file)
@@ -427,7 +427,7 @@ void Context::Enter() {
   i::Handle<i::Context> env = Utils::OpenHandle(this);
   thread_local.EnterContext(env);
 
-  thread_local.SaveContext(i::GlobalHandles::Create(i::Top::context()));
+  thread_local.SaveContext(i::Top::context());
   i::Top::set_context(*env);
 }
 
@@ -441,9 +441,8 @@ void Context::Exit() {
   }
 
   // Content of 'last_context' could be NULL.
-  i::Handle<i::Object> last_context = thread_local.RestoreContext();
-  i::Top::set_context(static_cast<i::Context*>(*last_context));
-  i::GlobalHandles::Destroy(last_context.location());
+  i::Context* last_context = thread_local.RestoreContext();
+  i::Top::set_context(last_context);
 }
 
 
@@ -3700,19 +3699,21 @@ char* HandleScopeImplementer::RestoreThreadHelper(char* storage) {
 }
 
 
-void HandleScopeImplementer::Iterate(
-    ObjectVisitor* v,
-    List<i::Object**>* blocks,
-    v8::ImplementationUtilities::HandleScopeData* handle_data) {
+void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
   // Iterate over all handles in the blocks except for the last.
-  for (int i = blocks->length() - 2; i >= 0; --i) {
-    Object** block = blocks->at(i);
+  for (int i = Blocks()->length() - 2; i >= 0; --i) {
+    Object** block = Blocks()->at(i);
     v->VisitPointers(block, &block[kHandleBlockSize]);
   }
 
   // Iterate over live handles in the last block (if any).
-  if (!blocks->is_empty()) {
-    v->VisitPointers(blocks->last(), handle_data->next);
+  if (!Blocks()->is_empty()) {
+    v->VisitPointers(Blocks()->last(), handle_scope_data_.next);
+  }
+
+  if (!saved_contexts_.is_empty()) {
+    Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
+    v->VisitPointers(start, start + saved_contexts_.length());
   }
 }
 
@@ -3720,18 +3721,15 @@ void HandleScopeImplementer::Iterate(
 void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
   v8::ImplementationUtilities::HandleScopeData* current =
       v8::ImplementationUtilities::CurrentHandleScope();
-  Iterate(v, thread_local.Blocks(), current);
+  thread_local.handle_scope_data_ = *current;
+  thread_local.IterateThis(v);
 }
 
 
 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
   HandleScopeImplementer* thread_local =
       reinterpret_cast<HandleScopeImplementer*>(storage);
-  List<internal::Object**>* blocks_of_archived_thread = thread_local->Blocks();
-  v8::ImplementationUtilities::HandleScopeData* handle_data_of_archived_thread =
-      &thread_local->handle_scope_data_;
-  Iterate(v, blocks_of_archived_thread, handle_data_of_archived_thread);
-
+  thread_local->IterateThis(v);
   return storage + ArchiveSpacePerThread();
 }
 
index ca8f523..9ae6307 100644 (file)
@@ -352,8 +352,8 @@ class HandleScopeImplementer {
   // contexts have been entered.
   inline Handle<Object> LastEnteredContext();
 
-  inline void SaveContext(Handle<Object> context);
-  inline Handle<Object> RestoreContext();
+  inline void SaveContext(Context* context);
+  inline Context* RestoreContext();
   inline bool HasSavedContexts();
 
   inline List<internal::Object**>* Blocks() { return &blocks; }
@@ -368,14 +368,12 @@ class HandleScopeImplementer {
   // Used as a stack to keep track of entered contexts.
   List<Handle<Object> > entered_contexts_;
   // Used as a stack to keep track of saved contexts.
-  List<Handle<Object> > saved_contexts_;
+  List<Context*> saved_contexts_;
   bool ignore_out_of_memory;
   // This is only used for threading support.
   v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
 
-  static void Iterate(ObjectVisitor* v,
-      List<internal::Object**>* blocks,
-      v8::ImplementationUtilities::HandleScopeData* handle_data);
+  void IterateThis(ObjectVisitor* v);
   char* RestoreThreadHelper(char* from);
   char* ArchiveThreadHelper(char* to);
 
@@ -386,12 +384,12 @@ class HandleScopeImplementer {
 static const int kHandleBlockSize = v8::internal::KB - 2;  // fit in one page
 
 
-void HandleScopeImplementer::SaveContext(Handle<Object> context) {
+void HandleScopeImplementer::SaveContext(Context* context) {
   saved_contexts_.Add(context);
 }
 
 
-Handle<Object> HandleScopeImplementer::RestoreContext() {
+Context* HandleScopeImplementer::RestoreContext() {
   return saved_contexts_.RemoveLast();
 }
 
index daf2378..920110f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2006-2009 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -88,23 +88,200 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
   // Enter a construct frame.
   __ EnterConstructFrame();
 
-  // Preserve the two incoming parameters
+  // Preserve the two incoming parameters on the stack.
   __ mov(r0, Operand(r0, LSL, kSmiTagSize));
-  __ push(r0);  // smi-tagged arguments count
-  __ push(r1);  // constructor function
+  __ push(r0);  // Smi-tagged arguments count.
+  __ push(r1);  // Constructor function.
+
+  // Use r7 for holding undefined which is used in several places below.
+  __ LoadRoot(r7, Heap::kUndefinedValueRootIndex);
+
+  // Try to allocate the object without transitioning into C code. If any of the
+  // preconditions is not met, the code bails out to the runtime call.
+  Label rt_call, allocated;
+  if (FLAG_inline_new) {
+    Label undo_allocation;
+#ifdef ENABLE_DEBUGGER_SUPPORT
+    ExternalReference debug_step_in_fp =
+        ExternalReference::debug_step_in_fp_address();
+    __ mov(r2, Operand(debug_step_in_fp));
+    __ ldr(r2, MemOperand(r2));
+    __ tst(r2, r2);
+    __ b(nz, &rt_call);
+#endif
+
+    // Load the initial map and verify that it is in fact a map.
+    // r1: constructor function
+    // r7: undefined
+    __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
+    __ tst(r2, Operand(kSmiTagMask));
+    __ b(eq, &rt_call);
+    __ CompareObjectType(r2, r3, r4, MAP_TYPE);
+    __ b(ne, &rt_call);
+
+    // Check that the constructor is not constructing a JSFunction (see comments
+    // in Runtime_NewObject in runtime.cc). In which case the initial map's
+    // instance type would be JS_FUNCTION_TYPE.
+    // r1: constructor function
+    // r2: initial map
+    // r7: undefined
+    __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE);
+    __ b(eq, &rt_call);
+
+    // Now allocate the JSObject on the heap.
+    // r1: constructor function
+    // r2: initial map
+    // r7: undefined
+    __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset));
+    __ AllocateObjectInNewSpace(r3, r4, r5, r6, &rt_call, NO_ALLOCATION_FLAGS);
+
+    // Allocated the JSObject, now initialize the fields. Map is set to initial
+    // map and properties and elements are set to empty fixed array.
+    // r1: constructor function
+    // r2: initial map
+    // r3: object size
+    // r4: JSObject (not tagged)
+    // r7: undefined
+    __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex);
+    __ mov(r5, r4);
+    ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
+    __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
+    ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
+    __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
+    ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset);
+    __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
+
+    // Fill all the in-object properties with undefined.
+    // r1: constructor function
+    // r2: initial map
+    // r3: object size (in words)
+    // r4: JSObject (not tagged)
+    // r5: First in-object property of JSObject (not tagged)
+    // r7: undefined
+    __ add(r6, r4, Operand(r3, LSL, kPointerSizeLog2));  // End of object.
+    ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize);
+    { Label loop, entry;
+      __ b(&entry);
+      __ bind(&loop);
+      __ str(r7, MemOperand(r5, kPointerSize, PostIndex));
+      __ bind(&entry);
+      __ cmp(r5, Operand(r6));
+      __ b(lt, &loop);
+    }
+
+    // Add the object tag to make the JSObject real, so that we can continue and
+    // jump into the continuation code at any time from now on. Any failures
+    // need to undo the allocation, so that the heap is in a consistent state
+    // and verifiable.
+    __ add(r4, r4, Operand(kHeapObjectTag));
+
+    // Check if a non-empty properties array is needed. Continue with allocated
+    // object if not fall through to runtime call if it is.
+    // r1: constructor function
+    // r4: JSObject
+    // r5: start of next object (not tagged)
+    // r7: undefined
+    __ ldrb(r3, FieldMemOperand(r2, Map::kUnusedPropertyFieldsOffset));
+    // The field instance sizes contains both pre-allocated property fields and
+    // in-object properties.
+    __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset));
+    __ and_(r6,
+            r0,
+            Operand(0x000000FF << Map::kPreAllocatedPropertyFieldsByte * 8));
+    __ add(r3, r3, Operand(r6, LSR, Map::kPreAllocatedPropertyFieldsByte * 8));
+    __ and_(r6, r0, Operand(0x000000FF << Map::kInObjectPropertiesByte * 8));
+    __ sub(r3, r3, Operand(r6, LSR, Map::kInObjectPropertiesByte * 8), SetCC);
+
+    // Done if no extra properties are to be allocated.
+    __ b(eq, &allocated);
+    __ Assert(pl, "Property allocation count failed.");
+
+    // Scale the number of elements by pointer size and add the header for
+    // FixedArrays to the start of the next object calculation from above.
+    // r1: constructor
+    // r3: number of elements in properties array
+    // r4: JSObject
+    // r5: start of next object
+    // r7: undefined
+    __ add(r0, r3, Operand(FixedArray::kHeaderSize / kPointerSize));
+    __ AllocateObjectInNewSpace(r0,
+                                r5,
+                                r6,
+                                r2,
+                                &undo_allocation,
+                                RESULT_CONTAINS_TOP);
+
+    // Initialize the FixedArray.
+    // r1: constructor
+    // r3: number of elements in properties array
+    // r4: JSObject
+    // r5: FixedArray (not tagged)
+    // r7: undefined
+    __ LoadRoot(r6, Heap::kFixedArrayMapRootIndex);
+    __ mov(r2, r5);
+    ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
+    __ str(r6, MemOperand(r2, kPointerSize, PostIndex));
+    ASSERT_EQ(1 * kPointerSize, Array::kLengthOffset);
+    __ str(r3, MemOperand(r2, kPointerSize, PostIndex));
+
+    // Initialize the fields to undefined.
+    // r1: constructor function
+    // r2: First element of FixedArray (not tagged)
+    // r3: number of elements in properties array
+    // r4: JSObject
+    // r5: FixedArray (not tagged)
+    // r7: undefined
+    __ add(r6, r2, Operand(r3, LSL, kPointerSizeLog2));  // End of object.
+    ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize);
+    { Label loop, entry;
+      __ b(&entry);
+      __ bind(&loop);
+      __ str(r7, MemOperand(r2, kPointerSize, PostIndex));
+      __ bind(&entry);
+      __ cmp(r2, Operand(r6));
+      __ b(lt, &loop);
+    }
+
+    // Store the initialized FixedArray into the properties field of
+    // the JSObject
+    // r1: constructor function
+    // r4: JSObject
+    // r5: FixedArray (not tagged)
+    __ add(r5, r5, Operand(kHeapObjectTag));  // Add the heap tag.
+    __ str(r5, FieldMemOperand(r4, JSObject::kPropertiesOffset));
+
+    // Continue with JSObject being successfully allocated
+    // r1: constructor function
+    // r4: JSObject
+    __ jmp(&allocated);
+
+    // Undo the setting of the new top so that the heap is verifiable. For
+    // example, the map's unused properties potentially do not match the
+    // allocated objects unused properties.
+    // r4: JSObject (previous new top)
+    __ bind(&undo_allocation);
+    __ UndoAllocationInNewSpace(r4, r5);
+  }
 
-  // Allocate the new receiver object.
+  // Allocate the new receiver object using the runtime call.
+  // r1: constructor function
+  __ bind(&rt_call);
   __ push(r1);  // argument for Runtime_NewObject
   __ CallRuntime(Runtime::kNewObject, 1);
-  __ push(r0);  // save the receiver
+  __ mov(r4, r0);
+
+  // Receiver for constructor call allocated.
+  // r4: JSObject
+  __ bind(&allocated);
+  __ push(r4);
 
   // Push the function and the allocated receiver from the stack.
   // sp[0]: receiver (newly allocated object)
   // sp[1]: constructor function
   // sp[2]: number of arguments (smi-tagged)
   __ ldr(r1, MemOperand(sp, kPointerSize));
-  __ push(r1);  // function
-  __ push(r0);  // receiver
+  __ push(r1);  // Constructor function.
+  __ push(r4);  // Receiver.
 
   // Reload the number of arguments from the stack.
   // r1: constructor function
@@ -194,6 +371,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
   __ LeaveConstructFrame();
   __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1));
   __ add(sp, sp, Operand(kPointerSize));
+  __ IncrementCounter(&Counters::constructed_objects, 1, r1, r2);
   __ Jump(lr);
 }
 
index b94aa10..7b3662d 100644 (file)
@@ -4950,12 +4950,12 @@ static void AllocateHeapNumber(
     Register scratch2) {  // Another scratch register.
   // Allocate an object in the heap for the heap number and tag it as a heap
   // object.
-  __ AllocateObjectInNewSpace(HeapNumber::kSize,
+  __ AllocateObjectInNewSpace(HeapNumber::kSize / kPointerSize,
                               result,
                               scratch1,
                               scratch2,
                               need_gc,
-                              true);
+                              TAG_OBJECT);
 
   // Get heap number map and store it in the allocated object.
   __ LoadRoot(scratch1, Heap::kHeapNumberMapRootIndex);
@@ -5623,7 +5623,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
   // argument, so give it a Smi.
   __ mov(r0, Operand(Smi::FromInt(0)));
   __ push(r0);
-  __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
+  __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1);
 
   __ StubReturn(1);
 }
@@ -5678,6 +5678,13 @@ void UnarySubStub::Generate(MacroAssembler* masm) {
 }
 
 
+int CEntryStub::MinorKey() {
+  ASSERT(result_size_ <= 2);
+  // Result returned in r0 or r0+r1 by default.
+  return 0;
+}
+
+
 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
   // r0 holds the exception.
 
@@ -6195,7 +6202,7 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
   // by calling the runtime system.
   __ bind(&slow);
   __ push(r1);
-  __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
+  __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1);
 }
 
 
@@ -6216,7 +6223,7 @@ void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
 
   // Do the runtime call to allocate the arguments object.
   __ bind(&runtime);
-  __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
+  __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
 }
 
 
diff --git a/deps/v8/src/arm/constants-arm.cc b/deps/v8/src/arm/constants-arm.cc
new file mode 100644 (file)
index 0000000..964bfe1
--- /dev/null
@@ -0,0 +1,92 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "constants-arm.h"
+
+
+namespace assembler {
+namespace arm {
+
+namespace v8i = v8::internal;
+
+
+// These register names are defined in a way to match the native disassembler
+// formatting. See for example the command "objdump -d <binary file>".
+const char* Registers::names_[kNumRegisters] = {
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+  "r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc",
+};
+
+
+// List of alias names which can be used when referring to ARM registers.
+const Registers::RegisterAlias Registers::aliases_[] = {
+  {10, "sl"},
+  {11, "r11"},
+  {12, "r12"},
+  {13, "r13"},
+  {14, "r14"},
+  {15, "r15"},
+  {kNoRegister, NULL}
+};
+
+
+const char* Registers::Name(int reg) {
+  const char* result;
+  if ((0 <= reg) && (reg < kNumRegisters)) {
+    result = names_[reg];
+  } else {
+    result = "noreg";
+  }
+  return result;
+}
+
+
+int Registers::Number(const char* name) {
+  // Look through the canonical names.
+  for (int i = 0; i < kNumRegisters; i++) {
+    if (strcmp(names_[i], name) == 0) {
+      return i;
+    }
+  }
+
+  // Look through the alias names.
+  int i = 0;
+  while (aliases_[i].reg != kNoRegister) {
+    if (strcmp(aliases_[i].name, name) == 0) {
+      return aliases_[i].reg;
+    }
+    i++;
+  }
+
+  // No register with the reguested name found.
+  return kNoRegister;
+}
+
+
+} }  // namespace assembler::arm
index f0311df..2f2b709 100644 (file)
 namespace assembler {
 namespace arm {
 
+// Number of registers in normal ARM mode.
+static const int kNumRegisters = 16;
+
+// PC is register 15.
+static const int kPCRegister = 15;
+static const int kNoRegister = -1;
+
 // Defines constants and accessor classes to assemble, disassemble and
 // simulate ARM instructions.
 //
@@ -269,6 +276,27 @@ class Instr {
 };
 
 
+// Helper functions for converting between register numbers and names.
+class Registers {
+ public:
+  // Return the name of the register.
+  static const char* Name(int reg);
+
+  // Lookup the register number for the name provided.
+  static int Number(const char* name);
+
+  struct RegisterAlias {
+    int reg;
+    const char *name;
+  };
+
+ private:
+  static const char* names_[kNumRegisters];
+  static const RegisterAlias aliases_[];
+};
+
+
+
 } }  // namespace assembler::arm
 
 #endif  // V8_ARM_CONSTANTS_ARM_H_
index bcfab6c..e142841 100644 (file)
@@ -179,12 +179,6 @@ void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
 }
 
 
-void Debug::GenerateReturnDebugBreakEntry(MacroAssembler* masm) {
-  // Generate nothing as this handling of debug break return is not done this
-  // way on ARM  - yet.
-}
-
-
 void Debug::GenerateStubNoRegistersDebugBreak(MacroAssembler* masm) {
   // Generate nothing as CodeStub CallFunction is not used on ARM.
 }
index 2638409..6431483 100644 (file)
@@ -57,6 +57,7 @@
 
 #include "v8.h"
 
+#include "constants-arm.h"
 #include "disasm.h"
 #include "macro-assembler.h"
 #include "platform.h"
@@ -898,16 +899,6 @@ namespace disasm {
 namespace v8i = v8::internal;
 
 
-static const int kMaxRegisters = 16;
-
-// These register names are defined in a way to match the native disassembler
-// formatting. See for example the command "objdump -d <binary file>".
-static const char* reg_names[kMaxRegisters] = {
-  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
-  "r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc",
-};
-
-
 const char* NameConverter::NameOfAddress(byte* addr) const {
   static v8::internal::EmbeddedVector<char, 32> tmp_buffer;
   v8::internal::OS::SNPrintF(tmp_buffer, "%p", addr);
@@ -921,13 +912,7 @@ const char* NameConverter::NameOfConstant(byte* addr) const {
 
 
 const char* NameConverter::NameOfCPURegister(int reg) const {
-  const char* result;
-  if ((0 <= reg) && (reg < kMaxRegisters)) {
-    result = reg_names[reg];
-  } else {
-    result = "noreg";
-  }
-  return result;
+  return assembler::arm::Registers::Name(reg);
 }
 
 
index 848d04b..d230b45 100644 (file)
@@ -391,7 +391,7 @@ void CallIC::Generate(MacroAssembler* masm,
   __ mov(r0, Operand(2));
   __ mov(r1, Operand(f));
 
-  CEntryStub stub;
+  CEntryStub stub(1);
   __ CallStub(&stub);
 
   // Move result to r1 and leave the internal frame.
@@ -503,7 +503,7 @@ void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ stm(db_w, sp, r2.bit() | r3.bit());
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 2);
+  __ TailCallRuntime(f, 2, 1);
 }
 
 
@@ -543,7 +543,7 @@ void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ ldm(ia, sp, r2.bit() | r3.bit());
   __ stm(db_w, sp, r2.bit() | r3.bit());
 
-  __ TailCallRuntime(f, 2);
+  __ TailCallRuntime(f, 2, 1);
 }
 
 
@@ -599,7 +599,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   __ ldm(ia, sp, r0.bit() | r1.bit());
   __ stm(db_w, sp, r0.bit() | r1.bit());
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2);
+  __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2, 1);
 
   // Fast case: Do the load.
   __ bind(&fast);
@@ -626,7 +626,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm,
   __ ldm(ia, sp, r2.bit() | r3.bit());
   __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
 
-  __ TailCallRuntime(f, 3);
+  __ TailCallRuntime(f, 3, 1);
 }
 
 
@@ -684,7 +684,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
   __ 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.
-  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
+  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
 
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
@@ -761,7 +761,7 @@ void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
 
   // Perform tail call to the entry.
   __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
+      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
 }
 
 
@@ -798,7 +798,7 @@ void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
 
   // Perform tail call to the entry.
   __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
+      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
 }
 
 
@@ -814,7 +814,7 @@ void StoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 3);
+  __ TailCallRuntime(f, 3, 1);
 }
 
 
index 2ca4898..de2db90 100644 (file)
@@ -56,6 +56,7 @@ MacroAssembler::MacroAssembler(void* buffer, int size)
 #if defined(USE_THUMB_INTERWORK)
 #if !defined(__ARM_ARCH_5T__) && \
   !defined(__ARM_ARCH_5TE__) &&  \
+  !defined(__ARM_ARCH_6__) &&  \
   !defined(__ARM_ARCH_7A__) &&   \
   !defined(__ARM_ARCH_7__)
 // add tests for other versions above v5t as required
@@ -773,7 +774,7 @@ void MacroAssembler::AllocateObjectInNewSpace(int object_size,
                                               Register scratch1,
                                               Register scratch2,
                                               Label* gc_required,
-                                              bool tag_allocated_object) {
+                                              AllocationFlags flags) {
   ASSERT(!result.is(scratch1));
   ASSERT(!scratch1.is(scratch2));
 
@@ -782,7 +783,18 @@ void MacroAssembler::AllocateObjectInNewSpace(int object_size,
   ExternalReference new_space_allocation_top =
       ExternalReference::new_space_allocation_top_address();
   mov(scratch1, Operand(new_space_allocation_top));
-  ldr(result, MemOperand(scratch1));
+  if ((flags & RESULT_CONTAINS_TOP) == 0) {
+    ldr(result, MemOperand(scratch1));
+  } else {
+#ifdef DEBUG
+    // Assert that result actually contains top on entry. scratch2 is used
+    // immediately below so this use of scratch2 does not cause difference with
+    // respect to register content between debug and release mode.
+    ldr(scratch2, MemOperand(scratch1));
+    cmp(result, scratch2);
+    Check(eq, "Unexpected allocation top");
+#endif
+  }
 
   // Calculate new top and bail out if new space is exhausted. Use result
   // to calculate the new top.
@@ -790,7 +802,7 @@ void MacroAssembler::AllocateObjectInNewSpace(int object_size,
       ExternalReference::new_space_allocation_limit_address();
   mov(scratch2, Operand(new_space_allocation_limit));
   ldr(scratch2, MemOperand(scratch2));
-  add(result, result, Operand(object_size));
+  add(result, result, Operand(object_size * kPointerSize));
   cmp(result, Operand(scratch2));
   b(hi, gc_required);
 
@@ -798,19 +810,98 @@ void MacroAssembler::AllocateObjectInNewSpace(int object_size,
   str(result, MemOperand(scratch1));
 
   // Tag and adjust back to start of new object.
-  if (tag_allocated_object) {
-    sub(result, result, Operand(object_size - kHeapObjectTag));
+  if ((flags & TAG_OBJECT) != 0) {
+    sub(result, result, Operand((object_size * kPointerSize) -
+                                kHeapObjectTag));
+  } else {
+    sub(result, result, Operand(object_size * kPointerSize));
+  }
+}
+
+
+void MacroAssembler::AllocateObjectInNewSpace(Register object_size,
+                                              Register result,
+                                              Register scratch1,
+                                              Register scratch2,
+                                              Label* gc_required,
+                                              AllocationFlags flags) {
+  ASSERT(!result.is(scratch1));
+  ASSERT(!scratch1.is(scratch2));
+
+  // Load address of new object into result and allocation top address into
+  // scratch1.
+  ExternalReference new_space_allocation_top =
+      ExternalReference::new_space_allocation_top_address();
+  mov(scratch1, Operand(new_space_allocation_top));
+  if ((flags & RESULT_CONTAINS_TOP) == 0) {
+    ldr(result, MemOperand(scratch1));
   } else {
-    sub(result, result, Operand(object_size));
+#ifdef DEBUG
+    // Assert that result actually contains top on entry. scratch2 is used
+    // immediately below so this use of scratch2 does not cause difference with
+    // respect to register content between debug and release mode.
+    ldr(scratch2, MemOperand(scratch1));
+    cmp(result, scratch2);
+    Check(eq, "Unexpected allocation top");
+#endif
+  }
+
+  // Calculate new top and bail out if new space is exhausted. Use result
+  // to calculate the new top. Object size is in words so a shift is required to
+  // get the number of bytes
+  ExternalReference new_space_allocation_limit =
+      ExternalReference::new_space_allocation_limit_address();
+  mov(scratch2, Operand(new_space_allocation_limit));
+  ldr(scratch2, MemOperand(scratch2));
+  add(result, result, Operand(object_size, LSL, kPointerSizeLog2));
+  cmp(result, Operand(scratch2));
+  b(hi, gc_required);
+
+  // Update allocation top. result temporarily holds the new top,
+  str(result, MemOperand(scratch1));
+
+  // Adjust back to start of new object.
+  sub(result, result, Operand(object_size, LSL, kPointerSizeLog2));
+
+  // Tag object if requested.
+  if ((flags & TAG_OBJECT) != 0) {
+    add(result, result, Operand(kHeapObjectTag));
   }
 }
 
 
+void MacroAssembler::UndoAllocationInNewSpace(Register object,
+                                              Register scratch) {
+  ExternalReference new_space_allocation_top =
+      ExternalReference::new_space_allocation_top_address();
+
+  // Make sure the object has no tag before resetting top.
+  and_(object, object, Operand(~kHeapObjectTagMask));
+#ifdef DEBUG
+  // Check that the object un-allocated is below the current top.
+  mov(scratch, Operand(new_space_allocation_top));
+  ldr(scratch, MemOperand(scratch));
+  cmp(object, scratch);
+  Check(lt, "Undo allocation of non allocated memory");
+#endif
+  // Write the address of the object to un-allocate as the current top.
+  mov(scratch, Operand(new_space_allocation_top));
+  str(object, MemOperand(scratch));
+}
+
+
 void MacroAssembler::CompareObjectType(Register function,
                                        Register map,
                                        Register type_reg,
                                        InstanceType type) {
   ldr(map, FieldMemOperand(function, HeapObject::kMapOffset));
+  CompareInstanceType(map, type_reg, type);
+}
+
+
+void MacroAssembler::CompareInstanceType(Register map,
+                                         Register type_reg,
+                                         InstanceType type) {
   ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
   cmp(type_reg, Operand(type));
 }
@@ -909,7 +1000,8 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) {
 
 
 void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
-                                     int num_arguments) {
+                                     int num_arguments,
+                                     int result_size) {
   // 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
@@ -925,7 +1017,7 @@ void MacroAssembler::JumpToBuiltin(const ExternalReference& builtin) {
   ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
 #endif
   mov(r1, Operand(builtin));
-  CEntryStub stub;
+  CEntryStub stub(1);
   Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
 }
 
index 4bbd980..f45cce5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2006-2009 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -38,34 +38,11 @@ namespace internal {
 const Register cp = { 8 };  // JavaScript context pointer
 
 
-// Helper types to make boolean flag easier to read at call-site.
-enum InvokeFlag {
-  CALL_FUNCTION,
-  JUMP_FUNCTION
-};
-
 enum InvokeJSFlags {
   CALL_JS,
   JUMP_JS
 };
 
-enum ExitJSFlag {
-  RETURN,
-  DO_NOT_RETURN
-};
-
-enum CodeLocation {
-  IN_JAVASCRIPT,
-  IN_JS_ENTRY,
-  IN_C_ENTRY
-};
-
-enum HandlerType {
-  TRY_CATCH_HANDLER,
-  TRY_FINALLY_HANDLER,
-  JS_ENTRY_HANDLER
-};
-
 
 // MacroAssembler implements a collection of frequently used macros.
 class MacroAssembler: public Assembler {
@@ -190,16 +167,28 @@ class MacroAssembler: public Assembler {
   // ---------------------------------------------------------------------------
   // Allocation support
 
-  // Allocate an object in new space. If the new space is exhausted control
-  // continues at the gc_required label. The allocated object is returned in
-  // result. If the flag tag_allocated_object is true the result is tagged as
-  // as a heap object.
+  // Allocate an object in new space. The object_size is specified in words (not
+  // bytes). If the new space is exhausted control continues at the gc_required
+  // label. The allocated object is returned in result. If the flag
+  // tag_allocated_object is true the result is tagged as as a heap object.
   void AllocateObjectInNewSpace(int object_size,
                                 Register result,
                                 Register scratch1,
                                 Register scratch2,
                                 Label* gc_required,
-                                bool tag_allocated_object);
+                                AllocationFlags flags);
+  void AllocateObjectInNewSpace(Register object_size,
+                                Register result,
+                                Register scratch1,
+                                Register scratch2,
+                                Label* gc_required,
+                                AllocationFlags flags);
+
+  // Undo allocation in new space. The object passed and objects allocated after
+  // it will no longer be allocated. The caller must make sure that no pointers
+  // are left to the object(s) no longer allocated as they would be invalid when
+  // allocation is undone.
+  void UndoAllocationInNewSpace(Register object, Register scratch);
 
   // ---------------------------------------------------------------------------
   // Support functions.
@@ -220,12 +209,21 @@ class MacroAssembler: public Assembler {
   // It leaves the map in the map register (unless the type_reg and map register
   // are the same register).  It leaves the heap object in the heap_object
   // register unless the heap_object register is the same register as one of the
-  // other // registers.
+  // other registers.
   void CompareObjectType(Register heap_object,
                          Register map,
                          Register type_reg,
                          InstanceType type);
 
+  // Compare instance type in a map.  map contains a valid map object whose
+  // object type should be compared with the given type.  This both
+  // sets the flags and leaves the object type in the type_reg register.  It
+  // leaves the heap object in the heap_object register unless the heap_object
+  // register is the same register as type_reg.
+  void CompareInstanceType(Register map,
+                           Register type_reg,
+                           InstanceType type);
+
   inline void BranchOnSmi(Register value, Label* smi_label) {
     tst(value, Operand(kSmiTagMask));
     b(eq, smi_label);
@@ -261,7 +259,9 @@ class MacroAssembler: public Assembler {
   // Tail call of a runtime routine (jump).
   // Like JumpToBuiltin, but also takes care of passing the number
   // of parameters.
-  void TailCallRuntime(const ExternalReference& ext, int num_arguments);
+  void TailCallRuntime(const ExternalReference& ext,
+                       int num_arguments,
+                       int result_size);
 
   // Jump to the builtin routine.
   void JumpToBuiltin(const ExternalReference& builtin);
index 252d783..2e75a61 100644 (file)
@@ -216,25 +216,29 @@ void RegExpMacroAssemblerARM::CheckCharacters(Vector<const uc16> str,
                                               int cp_offset,
                                               Label* on_failure,
                                               bool check_end_of_string) {
-  int byte_length = str.length() * char_size();
-  int byte_offset = cp_offset * char_size();
-  if (check_end_of_string) {
-    // Check that there are at least str.length() characters left in the input.
-    __ cmp(end_of_input_address(), Operand(-(byte_offset + byte_length)));
-    BranchOrBacktrack(gt, on_failure);
-  }
-
   if (on_failure == NULL) {
-    // Instead of inlining a backtrack, (re)use the global backtrack target.
+    // Instead of inlining a backtrack for each test, (re)use the global
+    // backtrack target.
     on_failure = &backtrack_label_;
   }
 
+  if (check_end_of_string) {
+    // Is last character of required match inside string.
+    CheckPosition(cp_offset + str.length() - 1, on_failure);
+  }
+
   __ add(r0, end_of_input_address(), Operand(current_input_offset()));
+  if (cp_offset != 0) {
+    int byte_offset = cp_offset * char_size();
+    __ add(r0, r0, Operand(byte_offset));
+  }
+
+  // r0 : Address of characters to match against str.
   int stored_high_byte = 0;
   for (int i = 0; i < str.length(); i++) {
     if (mode_ == ASCII) {
       __ ldrb(r1, MemOperand(r0, char_size(), PostIndex));
-      // str[i] is known to be an ASCII character.
+      ASSERT(str[i] <= String::kMaxAsciiCharCode);
       __ cmp(r1, Operand(str[i]));
     } else {
       __ ldrh(r1, MemOperand(r0, char_size(), PostIndex));
index e258e5a..70dfcd2 100644 (file)
@@ -70,7 +70,8 @@ class Debugger {
 
   Simulator* sim_;
 
-  bool GetValue(char* desc, int32_t* value);
+  int32_t GetRegisterValue(int regnum);
+  bool GetValue(const char* desc, int32_t* value);
 
   // Set or delete a breakpoint. Returns true if successful.
   bool SetBreakpoint(Instr* breakpc);
@@ -132,41 +133,19 @@ void Debugger::Stop(Instr* instr) {
 #endif
 
 
-static const char* reg_names[] = {  "r0",  "r1",  "r2",  "r3",
-                                    "r4",  "r5",  "r6",  "r7",
-                                    "r8",  "r9", "r10", "r11",
-                                   "r12", "r13", "r14", "r15",
-                                    "pc",  "lr",  "sp",  "ip",
-                                    "fp",  "sl", ""};
-
-static int   reg_nums[]  = {           0,     1,     2,     3,
-                                       4,     5,     6,     7,
-                                       8,     9,    10,    11,
-                                      12,    13,    14,    15,
-                                      15,    14,    13,    12,
-                                      11,    10};
-
-
-static int RegNameToRegNum(char* name) {
-  int reg = 0;
-  while (*reg_names[reg] != 0) {
-    if (strcmp(reg_names[reg], name) == 0) {
-      return reg_nums[reg];
-    }
-    reg++;
+int32_t Debugger::GetRegisterValue(int regnum) {
+  if (regnum == kPCRegister) {
+    return sim_->get_pc();
+  } else {
+    return sim_->get_register(regnum);
   }
-  return -1;
 }
 
 
-bool Debugger::GetValue(char* desc, int32_t* value) {
-  int regnum = RegNameToRegNum(desc);
-  if (regnum >= 0) {
-    if (regnum == 15) {
-      *value = sim_->get_pc();
-    } else {
-      *value = sim_->get_register(regnum);
-    }
+bool Debugger::GetValue(const char* desc, int32_t* value) {
+  int regnum = Registers::Number(desc);
+  if (regnum != kNoRegister) {
+    *value = GetRegisterValue(regnum);
     return true;
   } else {
     return SScanF(desc, "%i", value) == 1;
@@ -246,7 +225,7 @@ void Debugger::Debug() {
       v8::internal::EmbeddedVector<char, 256> buffer;
       dasm.InstructionDecode(buffer,
                              reinterpret_cast<byte*>(sim_->get_pc()));
-      PrintF("  0x%x  %s\n", sim_->get_pc(), buffer.start());
+      PrintF("  0x%08x  %s\n", sim_->get_pc(), buffer.start());
       last_pc = sim_->get_pc();
     }
     char* line = ReadLine("sim> ");
@@ -270,13 +249,20 @@ void Debugger::Debug() {
       } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
         if (args == 2) {
           int32_t value;
-          if (GetValue(arg1, &value)) {
-            PrintF("%s: %d 0x%x\n", arg1, value, value);
+          if (strcmp(arg1, "all") == 0) {
+            for (int i = 0; i < kNumRegisters; i++) {
+              value = GetRegisterValue(i);
+              PrintF("%3s: 0x%08x %10d\n", Registers::Name(i), value, value);
+            }
           } else {
-            PrintF("%s unrecognized\n", arg1);
+            if (GetValue(arg1, &value)) {
+              PrintF("%s: 0x%08x %d \n", arg1, value, value);
+            } else {
+              PrintF("%s unrecognized\n", arg1);
+            }
           }
         } else {
-          PrintF("print value\n");
+          PrintF("print <register>\n");
         }
       } else if ((strcmp(cmd, "po") == 0)
                  || (strcmp(cmd, "printobject") == 0)) {
@@ -284,16 +270,18 @@ void Debugger::Debug() {
           int32_t value;
           if (GetValue(arg1, &value)) {
             Object* obj = reinterpret_cast<Object*>(value);
-            USE(obj);
             PrintF("%s: \n", arg1);
-#if defined(DEBUG)
+#ifdef DEBUG
             obj->PrintLn();
-#endif  // defined(DEBUG)
+#else
+            obj->ShortPrint();
+            PrintF("\n");
+#endif
           } else {
             PrintF("%s unrecognized\n", arg1);
           }
         } else {
-          PrintF("printobject value\n");
+          PrintF("printobject <value>\n");
         }
       } else if (strcmp(cmd, "disasm") == 0) {
         disasm::NameConverter converter;
@@ -325,7 +313,7 @@ void Debugger::Debug() {
 
         while (cur < end) {
           dasm.InstructionDecode(buffer, cur);
-          PrintF("  0x%x  %s\n", cur, buffer.start());
+          PrintF("  0x%08x  %s\n", cur, buffer.start());
           cur += Instr::kInstrSize;
         }
       } else if (strcmp(cmd, "gdb") == 0) {
@@ -343,7 +331,7 @@ void Debugger::Debug() {
             PrintF("%s unrecognized\n", arg1);
           }
         } else {
-          PrintF("break addr\n");
+          PrintF("break <address>\n");
         }
       } else if (strcmp(cmd, "del") == 0) {
         if (!DeleteBreakpoint(NULL)) {
@@ -362,6 +350,30 @@ void Debugger::Debug() {
         } else {
           PrintF("Not at debugger stop.");
         }
+      } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
+        PrintF("cont\n");
+        PrintF("  continue execution (alias 'c')\n");
+        PrintF("stepi\n");
+        PrintF("  step one instruction (alias 'si')\n");
+        PrintF("print <register>\n");
+        PrintF("  print register content (alias 'p')\n");
+        PrintF("  use register name 'all' to print all registers\n");
+        PrintF("printobject <register>\n");
+        PrintF("  print an object from a register (alias 'po')\n");
+        PrintF("flags\n");
+        PrintF("  print flags\n");
+        PrintF("disasm [<instructions>]\n");
+        PrintF("disasm [[<address>] <instructions>]\n");
+        PrintF("  disassemble code, default is 10 instructions from pc\n");
+        PrintF("gdb\n");
+        PrintF("  enter gdb\n");
+        PrintF("break <address>\n");
+        PrintF("  set a break point on the address\n");
+        PrintF("del\n");
+        PrintF("  delete the breakpoint\n");
+        PrintF("unstop\n");
+        PrintF("  ignore the stop instruction at the current location");
+        PrintF(" from now on\n");
       } else {
         PrintF("Unknown command: %s\n", cmd);
       }
@@ -576,7 +588,7 @@ int Simulator::ReadW(int32_t addr, Instr* instr) {
     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
     return *ptr;
   }
-  PrintF("Unaligned read at %x\n", addr);
+  PrintF("Unaligned read at 0x%08x\n", addr);
   UNIMPLEMENTED();
   return 0;
 }
@@ -588,7 +600,7 @@ void Simulator::WriteW(int32_t addr, int value, Instr* instr) {
     *ptr = value;
     return;
   }
-  PrintF("Unaligned write at %x, pc=%p\n", addr, instr);
+  PrintF("Unaligned write at 0x%08x, pc=%p\n", addr, instr);
   UNIMPLEMENTED();
 }
 
@@ -598,7 +610,7 @@ uint16_t Simulator::ReadHU(int32_t addr, Instr* instr) {
     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
     return *ptr;
   }
-  PrintF("Unaligned unsigned halfword read at %x, pc=%p\n", addr, instr);
+  PrintF("Unaligned unsigned halfword read at 0x%08x, pc=%p\n", addr, instr);
   UNIMPLEMENTED();
   return 0;
 }
@@ -609,7 +621,7 @@ int16_t Simulator::ReadH(int32_t addr, Instr* instr) {
     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
     return *ptr;
   }
-  PrintF("Unaligned signed halfword read at %x\n", addr);
+  PrintF("Unaligned signed halfword read at 0x%08x\n", addr);
   UNIMPLEMENTED();
   return 0;
 }
@@ -621,7 +633,7 @@ void Simulator::WriteH(int32_t addr, uint16_t value, Instr* instr) {
     *ptr = value;
     return;
   }
-  PrintF("Unaligned unsigned halfword write at %x, pc=%p\n", addr, instr);
+  PrintF("Unaligned unsigned halfword write at 0x%08x, pc=%p\n", addr, instr);
   UNIMPLEMENTED();
 }
 
@@ -632,7 +644,7 @@ void Simulator::WriteH(int32_t addr, int16_t value, Instr* instr) {
     *ptr = value;
     return;
   }
-  PrintF("Unaligned halfword write at %x, pc=%p\n", addr, instr);
+  PrintF("Unaligned halfword write at 0x%08x, pc=%p\n", addr, instr);
   UNIMPLEMENTED();
 }
 
@@ -671,7 +683,7 @@ uintptr_t Simulator::StackLimit() const {
 
 // Unsupported instructions use Format to print an error and stop execution.
 void Simulator::Format(Instr* instr, const char* format) {
-  PrintF("Simulator found unsupported instruction:\n 0x%x: %s\n",
+  PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n",
          instr, format);
   UNIMPLEMENTED();
 }
@@ -1726,7 +1738,8 @@ void Simulator::DecodeUnconditional(Instr* instr) {
     uint16_t halfword = ReadH(addr, instr);
     set_register(rd, halfword);
   } else {
-    UNIMPLEMENTED();
+    Debugger dbg(this);
+    dbg.Stop(instr);
   }
 }
 
@@ -1741,7 +1754,7 @@ void Simulator::InstructionDecode(Instr* instr) {
     v8::internal::EmbeddedVector<char, 256> buffer;
     dasm.InstructionDecode(buffer,
                            reinterpret_cast<byte*>(instr));
-    PrintF("  0x%x  %s\n", instr, buffer.start());
+    PrintF("  0x%08x  %s\n", instr, buffer.start());
   }
   if (instr->ConditionField() == special_condition) {
     DecodeUnconditional(instr);
index 745b541..9e44cfa 100644 (file)
@@ -478,7 +478,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
   // Do tail-call to the runtime system.
   ExternalReference load_callback_property =
       ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
-  __ TailCallRuntime(load_callback_property, 5);
+  __ TailCallRuntime(load_callback_property, 5, 1);
 }
 
 
@@ -514,7 +514,7 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object,
   // Do tail-call to the runtime system.
   ExternalReference load_ic_property =
       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
-  __ TailCallRuntime(load_ic_property, 5);
+  __ TailCallRuntime(load_ic_property, 5, 1);
 }
 
 
@@ -884,7 +884,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
   // Do tail-call to the runtime system.
   ExternalReference store_callback_property =
       ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
-  __ TailCallRuntime(store_callback_property, 4);
+  __ TailCallRuntime(store_callback_property, 4, 1);
 
   // Handle store cache miss.
   __ bind(&miss);
@@ -936,7 +936,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
   // Do tail-call to the runtime system.
   ExternalReference store_ic_property =
       ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
-  __ TailCallRuntime(store_ic_property, 3);
+  __ TailCallRuntime(store_ic_property, 3, 1);
 
   // Handle store cache miss.
   __ bind(&miss);
@@ -1344,7 +1344,138 @@ Object* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
 
 Object* ConstructStubCompiler::CompileConstructStub(
     SharedFunctionInfo* shared) {
-  // Not implemented yet - just jump to generic stub.
+  // ----------- S t a t e -------------
+  //  -- r0    : argc
+  //  -- r1    : constructor
+  //  -- lr    : return address
+  //  -- [sp]  : last argument
+  // -----------------------------------
+  Label generic_stub_call;
+
+  // Use r7 for holding undefined which is used in several places below.
+  __ LoadRoot(r7, Heap::kUndefinedValueRootIndex);
+
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  // Check to see whether there are any break points in the function code. If
+  // there are jump to the generic constructor stub which calls the actual
+  // code for the function thereby hitting the break points.
+  __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
+  __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kDebugInfoOffset));
+  __ cmp(r2, r7);
+  __ b(ne, &generic_stub_call);
+#endif
+
+  // Load the initial map and verify that it is in fact a map.
+  // r1: constructor function
+  // r7: undefined
+  __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
+  __ tst(r2, Operand(kSmiTagMask));
+  __ b(eq, &generic_stub_call);
+  __ CompareObjectType(r2, r3, r4, MAP_TYPE);
+  __ b(ne, &generic_stub_call);
+
+#ifdef DEBUG
+  // Cannot construct functions this way.
+  // r0: argc
+  // r1: constructor function
+  // r2: initial map
+  // r7: undefined
+  __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE);
+  __ Check(ne, "Function constructed by construct stub.");
+#endif
+
+  // Now allocate the JSObject in new space.
+  // r0: argc
+  // r1: constructor function
+  // r2: initial map
+  // r7: undefined
+  __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset));
+  __ AllocateObjectInNewSpace(r3,
+                              r4,
+                              r5,
+                              r6,
+                              &generic_stub_call,
+                              NO_ALLOCATION_FLAGS);
+
+  // Allocated the JSObject, now initialize the fields. Map is set to initial
+  // map and properties and elements are set to empty fixed array.
+  // r0: argc
+  // r1: constructor function
+  // r2: initial map
+  // r3: object size (in words)
+  // r4: JSObject (not tagged)
+  // r7: undefined
+  __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex);
+  __ mov(r5, r4);
+  ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
+  __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
+  ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
+  __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
+  ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset);
+  __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
+
+  // Calculate the location of the first argument. The stack contains only the
+  // argc arguments.
+  __ add(r1, sp, Operand(r0, LSL, kPointerSizeLog2));
+
+  // Fill all the in-object properties with undefined.
+  // r0: argc
+  // r1: first argument
+  // r3: object size (in words)
+  // r4: JSObject (not tagged)
+  // r5: First in-object property of JSObject (not tagged)
+  // r7: undefined
+  // Fill the initialized properties with a constant value or a passed argument
+  // depending on the this.x = ...; assignment in the function.
+  for (int i = 0; i < shared->this_property_assignments_count(); i++) {
+    if (shared->IsThisPropertyAssignmentArgument(i)) {
+      Label not_passed, next;
+      // Check if the argument assigned to the property is actually passed.
+      int arg_number = shared->GetThisPropertyAssignmentArgument(i);
+      __ cmp(r0, Operand(arg_number));
+      __ b(le, &not_passed);
+      // Argument passed - find it on the stack.
+      __ ldr(r2, MemOperand(r1, (arg_number + 1) * -kPointerSize));
+      __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
+      __ b(&next);
+      __ bind(&not_passed);
+      // Set the property to undefined.
+      __ str(r7, MemOperand(r5, kPointerSize, PostIndex));
+      __ bind(&next);
+    } else {
+      // Set the property to the constant value.
+      Handle<Object> constant(shared->GetThisPropertyAssignmentConstant(i));
+      __ mov(r2, Operand(constant));
+      __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
+    }
+  }
+
+  // Fill the unused in-object property fields with undefined.
+  for (int i = shared->this_property_assignments_count();
+       i < shared->CalculateInObjectProperties();
+       i++) {
+      __ str(r7, MemOperand(r5, kPointerSize, PostIndex));
+  }
+
+  // r0: argc
+  // r4: JSObject (not tagged)
+  // Move argc to r1 and the JSObject to return to r0 and tag it.
+  __ mov(r1, r0);
+  __ mov(r0, r4);
+  __ orr(r0, r0, Operand(kHeapObjectTag));
+
+  // r0: JSObject
+  // r1: argc
+  // Remove caller arguments and receiver from the stack and return.
+  __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2));
+  __ add(sp, sp, Operand(kPointerSize));
+  __ IncrementCounter(&Counters::constructed_objects, 1, r1, r2);
+  __ IncrementCounter(&Counters::constructed_objects_stub, 1, r1, r2);
+  __ Jump(lr);
+
+  // Jump to the generic stub in case the specialized code cannot handle the
+  // construction.
+  __ bind(&generic_stub_call);
   Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric);
   Handle<Code> generic_construct_stub(code);
   __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
index a2c4562..c1daa57 100644 (file)
@@ -474,7 +474,7 @@ void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
   // Please note that the prototype property for function instances must be
   // writable.
   Handle<DescriptorArray> function_map_descriptors =
-      ComputeFunctionInstanceDescriptor(false, true);
+      ComputeFunctionInstanceDescriptor(false, false);
   fm->set_instance_descriptors(*function_map_descriptors);
 
   // Allocate the function map first and then patch the prototype later
index 4262dd2..195fe54 100644 (file)
@@ -609,11 +609,6 @@ static void Generate_Return_DebugBreak(MacroAssembler* masm) {
 }
 
 
-static void Generate_Return_DebugBreakEntry(MacroAssembler* masm) {
-  Debug::GenerateReturnDebugBreakEntry(masm);
-}
-
-
 static void Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm) {
   Debug::GenerateStubNoRegistersDebugBreak(masm);
 }
index 0f4a610..8df767a 100644 (file)
@@ -90,7 +90,6 @@ namespace internal {
 // Define list of builtins used by the debugger implemented in assembly.
 #define BUILTIN_LIST_DEBUG_A(V)                                \
   V(Return_DebugBreak,          BUILTIN, DEBUG_BREAK)          \
-  V(Return_DebugBreakEntry,     BUILTIN, DEBUG_BREAK)          \
   V(ConstructCall_DebugBreak,   BUILTIN, DEBUG_BREAK)          \
   V(StubNoRegisters_DebugBreak, BUILTIN, DEBUG_BREAK)          \
   V(LoadIC_DebugBreak,          LOAD_IC, DEBUG_BREAK)          \
index 4ecbaf4..b302e5b 100644 (file)
@@ -95,38 +95,6 @@ static inline void CheckNonEqualsHelper(const char* file,
   }
 }
 
-#ifdef V8_TARGET_ARCH_X64
-// Helper function used by the CHECK_EQ function when given intptr_t
-// arguments.  Should not be called directly.
-static inline void CheckEqualsHelper(const char* file,
-                                     int line,
-                                     const char* expected_source,
-                                     intptr_t expected,
-                                     const char* value_source,
-                                     intptr_t value) {
-  if (expected != value) {
-    V8_Fatal(file, line,
-             "CHECK_EQ(%s, %s) failed\n#   Expected: %i\n#   Found: %i",
-             expected_source, value_source, expected, value);
-  }
-}
-
-
-// Helper function used by the CHECK_NE function when given intptr_t
-// arguments.  Should not be called directly.
-static inline void CheckNonEqualsHelper(const char* file,
-                                        int line,
-                                        const char* unexpected_source,
-                                        intptr_t unexpected,
-                                        const char* value_source,
-                                        intptr_t value) {
-  if (unexpected == value) {
-    V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n#   Value: %i",
-             unexpected_source, value_source, value);
-  }
-}
-#endif  // V8_TARGET_ARCH_X64
-
 
 // Helper function used by the CHECK function when given string
 // arguments.  Should not be called directly.
index 8e516c0..9a00ae2 100644 (file)
@@ -517,7 +517,10 @@ const char* RuntimeStub::GetName() {
 
 
 void RuntimeStub::Generate(MacroAssembler* masm) {
-  masm->TailCallRuntime(ExternalReference(id_), num_arguments_);
+  Runtime::Function* f = Runtime::FunctionForId(id_);
+  masm->TailCallRuntime(ExternalReference(f),
+                        num_arguments_,
+                        f->result_size);
 }
 
 
index d6967b7..d03f4b6 100644 (file)
@@ -286,7 +286,7 @@ class CompareStub: public CodeStub {
 
 class CEntryStub : public CodeStub {
  public:
-  CEntryStub() { }
+  explicit CEntryStub(int result_size) : result_size_(result_size) { }
 
   void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }
 
@@ -302,10 +302,14 @@ class CEntryStub : public CodeStub {
   void GenerateThrowTOS(MacroAssembler* masm);
   void GenerateThrowUncatchable(MacroAssembler* masm,
                                 UncatchableExceptionType type);
-
  private:
+  // Number of pointers/values returned.
+  int result_size_;
+
   Major MajorKey() { return CEntry; }
-  int MinorKey() { return 0; }
+  // Minor key must differ if different result_size_ values means different
+  // code is generated.
+  int MinorKey();
 
   const char* GetName() { return "CEntryStub"; }
 };
@@ -313,7 +317,7 @@ class CEntryStub : public CodeStub {
 
 class CEntryDebugBreakStub : public CEntryStub {
  public:
-  CEntryDebugBreakStub() { }
+  CEntryDebugBreakStub() : CEntryStub(1) { }
 
   void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }
 
index 7082280..e4658b1 100644 (file)
@@ -159,8 +159,7 @@ Handle<Value> Shell::Write(const Arguments& args) {
       printf(" ");
     }
     v8::String::Utf8Value str(args[i]);
-    const char* cstr = ToCString(str);
-    printf("%s", cstr);
+    fwrite(*str, sizeof(**str), str.length(), stdout);
   }
   return Undefined();
 }
@@ -180,15 +179,15 @@ Handle<Value> Shell::Read(const Arguments& args) {
 
 
 Handle<Value> Shell::ReadLine(const Arguments& args) {
-  char line_buf[256];
-  if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
-    return ThrowException(String::New("Error reading line"));
+  i::SmartPointer<char> line(i::ReadLine(""));
+  if (*line == NULL) {
+    return Null();
   }
-  int len = strlen(line_buf);
-  if (line_buf[len - 1] == '\n') {
+  size_t len = strlen(*line);
+  if (len > 0 && line[len - 1] == '\n') {
     --len;
   }
-  return String::New(line_buf, len);
+  return String::New(*line, len);
 }
 
 
index da5be1f..14b5060 100644 (file)
@@ -102,7 +102,8 @@ Debug.ScriptCompilationType = { Host: 0,
 Debug.ScopeType = { Global: 0,
                     Local: 1,
                     With: 2,
-                    Closure: 3 };
+                    Closure: 3,
+                    Catch: 4 };
 
 
 // Current debug state.
@@ -900,6 +901,10 @@ function formatScope_(scope) {
       result += 'With, ';
       result += '#' + scope.object.ref + '#';
       break;
+    case Debug.ScopeType.Catch:
+      result += 'Catch, ';
+      result += '#' + scope.object.ref + '#';
+      break;
     case Debug.ScopeType.Closure:
       result += 'Closure';
       break;
index e341022..f3e11ae 100644 (file)
@@ -75,6 +75,9 @@ BreakLocationIterator::BreakLocationIterator(Handle<DebugInfo> debug_info,
                                              BreakLocatorType type) {
   debug_info_ = debug_info;
   type_ = type;
+  // Get the stub early to avoid possible GC during iterations. We may need
+  // this stub to detect debugger calls generated from debugger statements.
+  debug_break_stub_ = RuntimeStub(Runtime::kDebugBreak, 0).GetCode();
   reloc_iterator_ = NULL;
   reloc_iterator_original_ = NULL;
   Reset();  // Initialize the rest of the member variables.
@@ -126,6 +129,10 @@ void BreakLocationIterator::Next() {
         return;
       }
       if (code->kind() == Code::STUB) {
+        if (IsDebuggerStatement()) {
+          break_point_++;
+          return;
+        }
         if (type_ == ALL_BREAK_LOCATIONS) {
           if (Debug::IsBreakStub(code)) {
             break_point_++;
@@ -238,7 +245,7 @@ void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) {
   if (!HasBreakPoint()) {
     SetDebugBreak();
   }
-  ASSERT(IsDebugBreak());
+  ASSERT(IsDebugBreak() || IsDebuggerStatement());
   // Set the break point information.
   DebugInfo::SetBreakPoint(debug_info_, code_position(),
                            position(), statement_position(),
@@ -258,6 +265,11 @@ void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
 
 
 void BreakLocationIterator::SetOneShot() {
+  // Debugger statement always calls debugger. No need to modify it.
+  if (IsDebuggerStatement()) {
+    return;
+  }
+
   // If there is a real break point here no more to do.
   if (HasBreakPoint()) {
     ASSERT(IsDebugBreak());
@@ -270,6 +282,11 @@ void BreakLocationIterator::SetOneShot() {
 
 
 void BreakLocationIterator::ClearOneShot() {
+  // Debugger statement always calls debugger. No need to modify it.
+  if (IsDebuggerStatement()) {
+    return;
+  }
+
   // If there is a real break point here no more to do.
   if (HasBreakPoint()) {
     ASSERT(IsDebugBreak());
@@ -283,6 +300,11 @@ void BreakLocationIterator::ClearOneShot() {
 
 
 void BreakLocationIterator::SetDebugBreak() {
+  // Debugger statement always calls debugger. No need to modify it.
+  if (IsDebuggerStatement()) {
+    return;
+  }
+
   // If there is already a break point here just return. This might happen if
   // the same code is flooded with break points twice. Flooding the same
   // function twice might happen when stepping in a function with an exception
@@ -303,6 +325,11 @@ void BreakLocationIterator::SetDebugBreak() {
 
 
 void BreakLocationIterator::ClearDebugBreak() {
+  // Debugger statement always calls debugger. No need to modify it.
+  if (IsDebuggerStatement()) {
+    return;
+  }
+
   if (RelocInfo::IsJSReturn(rmode())) {
     // Restore the frame exit code.
     ClearDebugBreakAtReturn();
@@ -317,10 +344,10 @@ void BreakLocationIterator::ClearDebugBreak() {
 void BreakLocationIterator::PrepareStepIn() {
   HandleScope scope;
 
-  // Step in can only be prepared if currently positioned on an IC call or
-  // construct call.
+  // Step in can only be prepared if currently positioned on an IC call,
+  // construct call or CallFunction stub call.
   Address target = rinfo()->target_address();
-  Code* code = Code::GetCodeFromTargetAddress(target);
+  Handle<Code> code(Code::GetCodeFromTargetAddress(target));
   if (code->is_call_stub()) {
     // Step in through IC call is handled by the runtime system. Therefore make
     // sure that the any current IC is cleared and the runtime system is
@@ -334,11 +361,29 @@ void BreakLocationIterator::PrepareStepIn() {
       rinfo()->set_target_address(stub->entry());
     }
   } else {
+#ifdef DEBUG
+    // All the following stuff is needed only for assertion checks so the code
+    // is wrapped in ifdef.
+    Handle<Code> maybe_call_function_stub = code;
+    if (IsDebugBreak()) {
+      Address original_target = original_rinfo()->target_address();
+      maybe_call_function_stub =
+          Handle<Code>(Code::GetCodeFromTargetAddress(original_target));
+    }
+    bool is_call_function_stub =
+        (maybe_call_function_stub->kind() == Code::STUB &&
+         maybe_call_function_stub->major_key() == CodeStub::CallFunction);
+
     // Step in through construct call requires no changes to the running code.
     // Step in through getters/setters should already be prepared as well
     // because caller of this function (Debug::PrepareStep) is expected to
     // flood the top frame's function with one shot breakpoints.
-    ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub());
+    // Step in through CallFunction stub should also be prepared by caller of
+    // this function (Debug::PrepareStep) which should flood target function
+    // with breakpoints.
+    ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub()
+           || is_call_function_stub);
+#endif
   }
 }
 
@@ -409,6 +454,21 @@ void BreakLocationIterator::ClearDebugBreakAtIC() {
 }
 
 
+bool BreakLocationIterator::IsDebuggerStatement() {
+  if (RelocInfo::IsCodeTarget(rmode())) {
+    Address target = original_rinfo()->target_address();
+    Code* code = Code::GetCodeFromTargetAddress(target);
+    if (code->kind() == Code::STUB) {
+      CodeStub::Major major_key = code->major_key();
+      if (major_key == CodeStub::Runtime) {
+        return (*debug_break_stub_ == code);
+      }
+    }
+  }
+  return false;
+}
+
+
 Object* BreakLocationIterator::BreakPointObjects() {
   return debug_info_->GetBreakPointObjects(code_position());
 }
@@ -458,6 +518,7 @@ void Debug::ThreadInit() {
   thread_local_.step_count_ = 0;
   thread_local_.last_fp_ = 0;
   thread_local_.step_into_fp_ = 0;
+  thread_local_.step_out_fp_ = 0;
   thread_local_.after_break_target_ = 0;
   thread_local_.debugger_entry_ = NULL;
   thread_local_.pending_interrupts_ = 0;
@@ -502,7 +563,6 @@ bool Debug::break_on_exception_ = false;
 bool Debug::break_on_uncaught_exception_ = true;
 
 Handle<Context> Debug::debug_context_ = Handle<Context>();
-Code* Debug::debug_break_return_entry_ = NULL;
 Code* Debug::debug_break_return_ = NULL;
 
 
@@ -583,11 +643,6 @@ void ScriptCache::HandleWeakScript(v8::Persistent<v8::Value> obj, void* data) {
 void Debug::Setup(bool create_heap_objects) {
   ThreadInit();
   if (create_heap_objects) {
-    // Get code to handle entry to debug break on return.
-    debug_break_return_entry_ =
-        Builtins::builtin(Builtins::Return_DebugBreakEntry);
-    ASSERT(debug_break_return_entry_->IsCode());
-
     // Get code to handle debug break on return.
     debug_break_return_ =
         Builtins::builtin(Builtins::Return_DebugBreak);
@@ -749,7 +804,6 @@ void Debug::PreemptionWhileInDebugger() {
 
 
 void Debug::Iterate(ObjectVisitor* v) {
-  v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_entry_)));
   v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_)));
 }
 
@@ -804,11 +858,18 @@ Object* Debug::Break(Arguments args) {
     break_points_hit = CheckBreakPoints(break_point_objects);
   }
 
-  // Notify debugger if a real break point is triggered or if performing single
-  // stepping with no more steps to perform. Otherwise do another step.
-  if (!break_points_hit->IsUndefined() ||
-    (thread_local_.last_step_action_ != StepNone &&
-     thread_local_.step_count_ == 0)) {
+  // If step out is active skip everything until the frame where we need to step
+  // out to is reached, unless real breakpoint is hit.
+  if (Debug::StepOutActive() && frame->fp() != Debug::step_out_fp() &&
+      break_points_hit->IsUndefined() ) {
+      // Step count should always be 0 for StepOut.
+      ASSERT(thread_local_.step_count_ == 0);
+  } else if (!break_points_hit->IsUndefined() ||
+             (thread_local_.last_step_action_ != StepNone &&
+              thread_local_.step_count_ == 0)) {
+    // Notify debugger if a real break point is triggered or if performing
+    // single stepping with no more steps to perform. Otherwise do another step.
+
     // Clear all current stepping setup.
     ClearStepping();
 
@@ -1044,7 +1105,13 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
 
   // Remember this step action and count.
   thread_local_.last_step_action_ = step_action;
-  thread_local_.step_count_ = step_count;
+  if (step_action == StepOut) {
+    // For step out target frame will be found on the stack so there is no need
+    // to set step counter for it. It's expected to always be 0 for StepOut.
+    thread_local_.step_count_ = 0;
+  } else {
+    thread_local_.step_count_ = step_count;
+  }
 
   // Get the frame where the execution has stopped and skip the debug frame if
   // any. The debug frame will only be present if execution was stopped due to
@@ -1092,6 +1159,7 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
   bool is_call_target = false;
   bool is_load_or_store = false;
   bool is_inline_cache_stub = false;
+  Handle<Code> call_function_stub;
   if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
     Address target = it.rinfo()->target_address();
     Code* code = Code::GetCodeFromTargetAddress(target);
@@ -1102,19 +1170,51 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
       is_inline_cache_stub = true;
       is_load_or_store = !is_call_target;
     }
+
+    // Check if target code is CallFunction stub.
+    Code* maybe_call_function_stub = code;
+    // If there is a breakpoint at this line look at the original code to
+    // check if it is a CallFunction stub.
+    if (it.IsDebugBreak()) {
+      Address original_target = it.original_rinfo()->target_address();
+      maybe_call_function_stub =
+          Code::GetCodeFromTargetAddress(original_target);
+    }
+    if (maybe_call_function_stub->kind() == Code::STUB &&
+        maybe_call_function_stub->major_key() == CodeStub::CallFunction) {
+      // Save reference to the code as we may need it to find out arguments
+      // count for 'step in' later.
+      call_function_stub = Handle<Code>(maybe_call_function_stub);
+    }
   }
 
   // If this is the last break code target step out is the only possibility.
   if (it.IsExit() || step_action == StepOut) {
+    if (step_action == StepOut) {
+      // Skip step_count frames starting with the current one.
+      while (step_count-- > 0 && !frames_it.done()) {
+        frames_it.Advance();
+      }
+    } else {
+      ASSERT(it.IsExit());
+      frames_it.Advance();
+    }
+    // Skip builtin functions on the stack.
+    while (!frames_it.done() &&
+           JSFunction::cast(frames_it.frame()->function())->IsBuiltin()) {
+      frames_it.Advance();
+    }
     // Step out: If there is a JavaScript caller frame, we need to
     // flood it with breakpoints.
-    frames_it.Advance();
     if (!frames_it.done()) {
       // Fill the function to return to with one-shot break points.
       JSFunction* function = JSFunction::cast(frames_it.frame()->function());
       FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
+      // Set target frame pointer.
+      ActivateStepOut(frames_it.frame());
     }
-  } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()))
+  } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) ||
+               !call_function_stub.is_null())
              || step_action == StepNext || step_action == StepMin) {
     // Step next or step min.
 
@@ -1126,6 +1226,45 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
         debug_info->code()->SourceStatementPosition(frame->pc());
     thread_local_.last_fp_ = frame->fp();
   } else {
+    // If it's CallFunction stub ensure target function is compiled and flood
+    // it with one shot breakpoints.
+    if (!call_function_stub.is_null()) {
+      // Find out number of arguments from the stub minor key.
+      // Reverse lookup required as the minor key cannot be retrieved
+      // from the code object.
+      Handle<Object> obj(
+          Heap::code_stubs()->SlowReverseLookup(*call_function_stub));
+      ASSERT(*obj != Heap::undefined_value());
+      ASSERT(obj->IsSmi());
+      // Get the STUB key and extract major and minor key.
+      uint32_t key = Smi::cast(*obj)->value();
+      // Argc in the stub is the number of arguments passed - not the
+      // expected arguments of the called function.
+      int call_function_arg_count = CodeStub::MinorKeyFromKey(key);
+      ASSERT(call_function_stub->major_key() ==
+             CodeStub::MajorKeyFromKey(key));
+
+      // Find target function on the expression stack.
+      // Expression stack lools like this (top to bottom):
+      // argN
+      // ...
+      // arg0
+      // Receiver
+      // Function to call
+      int expressions_count = frame->ComputeExpressionsCount();
+      ASSERT(expressions_count - 2 - call_function_arg_count >= 0);
+      Object* fun = frame->GetExpression(
+          expressions_count - 2 - call_function_arg_count);
+      if (fun->IsJSFunction()) {
+        Handle<JSFunction> js_function(JSFunction::cast(fun));
+        // Don't step into builtins.
+        if (!js_function->IsBuiltin()) {
+          // It will also compile target function if it's not compiled yet.
+          FloodWithOneShot(Handle<SharedFunctionInfo>(js_function->shared()));
+        }
+      }
+    }
+
     // Fill the current function with one-shot break points even for step in on
     // a call target as the function called might be a native function for
     // which step in will not stop. It also prepares for stepping in
@@ -1328,6 +1467,7 @@ void Debug::ClearStepping() {
   // Clear the various stepping setup.
   ClearOneShot();
   ClearStepIn();
+  ClearStepOut();
   ClearStepNext();
 
   // Clear multiple step counter.
@@ -1355,6 +1495,7 @@ void Debug::ClearOneShot() {
 
 
 void Debug::ActivateStepIn(StackFrame* frame) {
+  ASSERT(!StepOutActive());
   thread_local_.step_into_fp_ = frame->fp();
 }
 
@@ -1364,6 +1505,17 @@ void Debug::ClearStepIn() {
 }
 
 
+void Debug::ActivateStepOut(StackFrame* frame) {
+  ASSERT(!StepInActive());
+  thread_local_.step_out_fp_ = frame->fp();
+}
+
+
+void Debug::ClearStepOut() {
+  thread_local_.step_out_fp_ = 0;
+}
+
+
 void Debug::ClearStepNext() {
   thread_local_.last_step_action_ = StepNone;
   thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
@@ -1455,26 +1607,25 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
   Address addr = frame->pc() - Assembler::kPatchReturnSequenceLength;
 
   // Check if the location is at JS exit.
-  bool at_js_exit = false;
+  bool at_js_return = false;
+  bool break_at_js_return_active = false;
   RelocIterator it(debug_info->code());
   while (!it.done()) {
     if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
-      at_js_exit = (it.rinfo()->pc() ==
-                        addr - Assembler::kPatchReturnSequenceAddressOffset);
+      at_js_return = (it.rinfo()->pc() ==
+          addr - Assembler::kPatchReturnSequenceAddressOffset);
+      break_at_js_return_active = it.rinfo()->IsCallInstruction();
     }
     it.next();
   }
 
   // Handle the jump to continue execution after break point depending on the
   // break location.
-  if (at_js_exit) {
-    // First check if the call in the code is still the debug break return
-    // entry code. If it is the break point is still active. If not the break
-    // point was removed during break point processing.
-    if (Assembler::target_address_at(addr) ==
-        debug_break_return_entry()->entry()) {
-      // Break point still active. Jump to the corresponding place in the
-      // original code.
+  if (at_js_return) {
+    // If the break point as return is still active jump to the corresponding
+    // place in the original code. If not the break point was removed during
+    // break point processing.
+    if (break_at_js_return_active) {
       addr +=  original_code->instruction_start() - code->instruction_start();
     }
 
index 5b0273a..d6b2c08 100644 (file)
@@ -119,6 +119,8 @@ class BreakLocationIterator {
     return reloc_iterator_original_->rinfo()->rmode();
   }
 
+  bool IsDebuggerStatement();
+
  protected:
   bool RinfoDone() const;
   void RinfoNext();
@@ -128,6 +130,7 @@ class BreakLocationIterator {
   int position_;
   int statement_position_;
   Handle<DebugInfo> debug_info_;
+  Handle<Code> debug_break_stub_;
   RelocIterator* reloc_iterator_;
   RelocIterator* reloc_iterator_original_;
 
@@ -279,6 +282,9 @@ class Debug {
   static Address step_in_fp() { return thread_local_.step_into_fp_; }
   static Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; }
 
+  static bool StepOutActive() { return thread_local_.step_out_fp_ != 0; }
+  static Address step_out_fp() { return thread_local_.step_out_fp_; }
+
   static EnterDebugger* debugger_entry() {
     return thread_local_.debugger_entry_;
   }
@@ -329,10 +335,8 @@ class Debug {
     return &registers_[r];
   }
 
-  // Address of the debug break return entry code.
-  static Code* debug_break_return_entry() { return debug_break_return_entry_; }
-
-  // Support for getting the address of the debug break on return code.
+  // Access to the debug break on return code.
+  static Code* debug_break_return() { return debug_break_return_; }
   static Code** debug_break_return_address() {
     return &debug_break_return_;
   }
@@ -379,7 +383,6 @@ class Debug {
   static void GenerateKeyedStoreICDebugBreak(MacroAssembler* masm);
   static void GenerateConstructCallDebugBreak(MacroAssembler* masm);
   static void GenerateReturnDebugBreak(MacroAssembler* masm);
-  static void GenerateReturnDebugBreakEntry(MacroAssembler* masm);
   static void GenerateStubNoRegistersDebugBreak(MacroAssembler* masm);
 
   // Called from stub-cache.cc.
@@ -390,6 +393,8 @@ class Debug {
   static void ClearOneShot();
   static void ActivateStepIn(StackFrame* frame);
   static void ClearStepIn();
+  static void ActivateStepOut(StackFrame* frame);
+  static void ClearStepOut();
   static void ClearStepNext();
   // Returns whether the compile succeeded.
   static bool EnsureCompiled(Handle<SharedFunctionInfo> shared);
@@ -442,6 +447,10 @@ class Debug {
     // Frame pointer for frame from which step in was performed.
     Address step_into_fp_;
 
+    // Frame pointer for the frame where debugger should be called when current
+    // step out action is completed.
+    Address step_out_fp_;
+
     // Storage location for jump when exiting debug break calls.
     Address after_break_target_;
 
@@ -457,9 +466,6 @@ class Debug {
   static ThreadLocal thread_local_;
   static void ThreadInit();
 
-  // Code object for debug break return entry code.
-  static Code* debug_break_return_entry_;
-
   // Code to call for handling debug break on return.
   static Code* debug_break_return_;
 
index c29815e..949dd80 100644 (file)
@@ -77,11 +77,11 @@ int Heap::semispace_size_  = 512*KB;
 int Heap::old_generation_size_ = 128*MB;
 int Heap::initial_semispace_size_ = 128*KB;
 #elif defined(V8_TARGET_ARCH_X64)
-int Heap::semispace_size_  = 8*MB;
+int Heap::semispace_size_  = 16*MB;
 int Heap::old_generation_size_ = 1*GB;
 int Heap::initial_semispace_size_ = 1*MB;
 #else
-int Heap::semispace_size_  = 4*MB;
+int Heap::semispace_size_  = 8*MB;
 int Heap::old_generation_size_ = 512*MB;
 int Heap::initial_semispace_size_ = 512*KB;
 #endif
@@ -1319,7 +1319,7 @@ bool Heap::CreateApiObjects() {
 
 
 void Heap::CreateCEntryStub() {
-  CEntryStub stub;
+  CEntryStub stub(1);
   set_c_entry_code(*stub.GetCode());
 }
 
@@ -2795,7 +2795,9 @@ STRUCT_LIST(MAKE_CASE)
 
 
 bool Heap::IdleNotification() {
-  static const int kIdlesBeforeCollection = 7;
+  static const int kIdlesBeforeScavenge = 4;
+  static const int kIdlesBeforeMarkSweep = 7;
+  static const int kIdlesBeforeMarkCompact = 8;
   static int number_idle_notifications = 0;
   static int last_gc_count = gc_count_;
 
@@ -2808,19 +2810,22 @@ bool Heap::IdleNotification() {
     last_gc_count = gc_count_;
   }
 
-  if (number_idle_notifications >= kIdlesBeforeCollection) {
-    // The first time through we collect without forcing compaction.
-    // The second time through we force compaction and quit.
-    bool force_compaction =
-        number_idle_notifications > kIdlesBeforeCollection;
-    CollectAllGarbage(force_compaction);
+  if (number_idle_notifications == kIdlesBeforeScavenge) {
+    CollectGarbage(0, NEW_SPACE);
+    new_space_.Shrink();
     last_gc_count = gc_count_;
-    if (force_compaction) {
-      // Shrink new space.
-      new_space_.Shrink();
-      number_idle_notifications = 0;
-      finished = true;
-    }
+
+  } else if (number_idle_notifications == kIdlesBeforeMarkSweep) {
+    CollectAllGarbage(false);
+    new_space_.Shrink();
+    last_gc_count = gc_count_;
+
+  } else if (number_idle_notifications == kIdlesBeforeMarkCompact) {
+    CollectAllGarbage(true);
+    new_space_.Shrink();
+    last_gc_count = gc_count_;
+    number_idle_notifications = 0;
+    finished = true;
   }
 
   // Uncommit unused memory in new space.
@@ -3185,63 +3190,49 @@ bool Heap::Setup(bool create_heap_objects) {
     if (!ConfigureHeapDefault()) return false;
   }
 
-  // Setup memory allocator and allocate an initial chunk of memory.  The
-  // initial chunk is double the size of the new space to ensure that we can
-  // find a pair of semispaces that are contiguous and aligned to their size.
+  // Setup memory allocator and reserve a chunk of memory for new
+  // space.  The chunk is double the size of the new space to ensure
+  // that we can find a pair of semispaces that are contiguous and
+  // aligned to their size.
   if (!MemoryAllocator::Setup(MaxCapacity())) return false;
-  void* chunk
-      MemoryAllocator::ReserveInitialChunk(2 * young_generation_size_);
+  void* chunk =
+      MemoryAllocator::ReserveInitialChunk(2 * young_generation_size_);
   if (chunk == NULL) return false;
 
-  // Put the initial chunk of the old space at the start of the initial
-  // chunk, then the two new space semispaces, then the initial chunk of
-  // code space.  Align the pair of semispaces to their size, which must be
-  // a power of 2.
+  // Align the pair of semispaces to their size, which must be a power
+  // of 2.
   ASSERT(IsPowerOf2(young_generation_size_));
-  Address code_space_start = reinterpret_cast<Address>(chunk);
-  Address new_space_start = RoundUp(code_space_start, young_generation_size_);
-  Address old_space_start = new_space_start + young_generation_size_;
-  int code_space_size = new_space_start - code_space_start;
-  int old_space_size = young_generation_size_ - code_space_size;
-
-  // Initialize new space.
+  Address new_space_start =
+      RoundUp(reinterpret_cast<byte*>(chunk), young_generation_size_);
   if (!new_space_.Setup(new_space_start, young_generation_size_)) return false;
 
-  // Initialize old space, set the maximum capacity to the old generation
-  // size. It will not contain code.
+  // Initialize old pointer space.
   old_pointer_space_ =
       new OldSpace(old_generation_size_, OLD_POINTER_SPACE, NOT_EXECUTABLE);
   if (old_pointer_space_ == NULL) return false;
-  if (!old_pointer_space_->Setup(old_space_start, old_space_size >> 1)) {
-    return false;
-  }
+  if (!old_pointer_space_->Setup(NULL, 0)) return false;
+
+  // Initialize old data space.
   old_data_space_ =
       new OldSpace(old_generation_size_, OLD_DATA_SPACE, NOT_EXECUTABLE);
   if (old_data_space_ == NULL) return false;
-  if (!old_data_space_->Setup(old_space_start + (old_space_size >> 1),
-                              old_space_size >> 1)) {
-    return false;
-  }
+  if (!old_data_space_->Setup(NULL, 0)) return false;
 
   // Initialize the code space, set its maximum capacity to the old
   // generation size. It needs executable memory.
   code_space_ =
       new OldSpace(old_generation_size_, CODE_SPACE, EXECUTABLE);
   if (code_space_ == NULL) return false;
-  if (!code_space_->Setup(code_space_start, code_space_size)) return false;
+  if (!code_space_->Setup(NULL, 0)) return false;
 
   // Initialize map space.
   map_space_ = new MapSpace(kMaxMapSpaceSize, MAP_SPACE);
   if (map_space_ == NULL) return false;
-  // Setting up a paged space without giving it a virtual memory range big
-  // enough to hold at least a page will cause it to allocate.
   if (!map_space_->Setup(NULL, 0)) return false;
 
   // Initialize global property cell space.
   cell_space_ = new CellSpace(old_generation_size_, CELL_SPACE);
   if (cell_space_ == NULL) return false;
-  // Setting up a paged space without giving it a virtual memory range big
-  // enough to hold at least a page will cause it to allocate.
   if (!cell_space_->Setup(NULL, 0)) return false;
 
   // The large object code space may contain code or data.  We set the memory
@@ -3563,7 +3554,7 @@ namespace {
 class JSConstructorProfile BASE_EMBEDDED {
  public:
   JSConstructorProfile() : zscope_(DELETE_ON_EXIT) {}
-  void CollectStats(JSObject* obj);
+  void CollectStats(HeapObject* obj);
   void PrintStats();
   // Used by ZoneSplayTree::ForEach.
   void Call(String* name, const NumberAndSizeInfo& number_and_size);
@@ -3608,33 +3599,36 @@ int JSConstructorProfile::CalculateJSObjectNetworkSize(JSObject* obj) {
 
 void JSConstructorProfile::Call(String* name,
                                 const NumberAndSizeInfo& number_and_size) {
-  SmartPointer<char> s_name;
-  if (name != NULL) {
-    s_name = name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
-  }
+  ASSERT(name != NULL);
+  SmartPointer<char> s_name(
+      name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL));
   LOG(HeapSampleJSConstructorEvent(*s_name,
                                    number_and_size.number(),
                                    number_and_size.bytes()));
 }
 
 
-void JSConstructorProfile::CollectStats(JSObject* obj) {
-  String* constructor_func = NULL;
-  if (obj->map()->constructor()->IsJSFunction()) {
-    JSFunction* constructor = JSFunction::cast(obj->map()->constructor());
-    SharedFunctionInfo* sfi = constructor->shared();
-    String* name = String::cast(sfi->name());
-    constructor_func = name->length() > 0 ? name : sfi->inferred_name();
-  } else if (obj->IsJSFunction()) {
-    constructor_func = Heap::function_class_symbol();
+void JSConstructorProfile::CollectStats(HeapObject* obj) {
+  String* constructor = NULL;
+  int size;
+  if (obj->IsString()) {
+    constructor = Heap::String_symbol();
+    size = obj->Size();
+  } else if (obj->IsJSObject()) {
+    JSObject* js_obj = JSObject::cast(obj);
+    constructor = js_obj->constructor_name();
+    size = CalculateJSObjectNetworkSize(js_obj);
+  } else {
+    return;
   }
+
   JSObjectsInfoTree::Locator loc;
-  if (!js_objects_info_tree_.Find(constructor_func, &loc)) {
-    js_objects_info_tree_.Insert(constructor_func, &loc);
+  if (!js_objects_info_tree_.Find(constructor, &loc)) {
+    js_objects_info_tree_.Insert(constructor, &loc);
   }
   NumberAndSizeInfo number_and_size = loc.value();
   number_and_size.increment_number(1);
-  number_and_size.increment_bytes(CalculateJSObjectNetworkSize(obj));
+  number_and_size.increment_bytes(size);
   loc.set_value(number_and_size);
 }
 
@@ -3676,9 +3670,7 @@ void HeapProfiler::WriteSample() {
   while (iterator.has_next()) {
     HeapObject* obj = iterator.next();
     CollectStats(obj, info);
-    if (obj->IsJSObject()) {
-      js_cons_profile.CollectStats(JSObject::cast(obj));
-    }
+    js_cons_profile.CollectStats(obj);
   }
 
   // Lump all the string types together.
index 55dc92d..7793e49 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2006-2009 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -129,11 +129,12 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
     // eax: initial map
     __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset));
     __ shl(edi, kPointerSizeLog2);
-    // Make sure that the maximum heap object size will never cause us
-    // problem here, because it is always greater than the maximum
-    // instance size that can be represented in a byte.
-    ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize);
-    __ AllocateObjectInNewSpace(edi, ebx, edi, no_reg, &rt_call, false);
+    __ AllocateObjectInNewSpace(edi,
+                                ebx,
+                                edi,
+                                no_reg,
+                                &rt_call,
+                                NO_ALLOCATION_FLAGS);
     // Allocated the JSObject, now initialize the fields.
     // eax: initial map
     // ebx: JSObject
@@ -188,8 +189,6 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
     // ebx: JSObject
     // edi: start of next object (will be start of FixedArray)
     // edx: number of elements in properties array
-    ASSERT(Heap::MaxObjectSizeInPagedSpace() >
-           (FixedArray::kHeaderSize + 255*kPointerSize));
     __ AllocateObjectInNewSpace(FixedArray::kHeaderSize,
                                 times_pointer_size,
                                 edx,
@@ -197,7 +196,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
                                 ecx,
                                 no_reg,
                                 &undo_allocation,
-                                true);
+                                RESULT_CONTAINS_TOP);
 
     // Initialize the FixedArray.
     // ebx: JSObject
@@ -245,10 +244,10 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
   }
 
   // Allocate the new receiver object using the runtime call.
-  // edi: function (constructor)
   __ bind(&rt_call);
   // Must restore edi (constructor) before calling runtime.
   __ mov(edi, Operand(esp, 0));
+  // edi: function (constructor)
   __ push(edi);
   __ CallRuntime(Runtime::kNewObject, 1);
   __ mov(ebx, Operand(eax));  // store result in ebx
index a9face1..400a360 100644 (file)
@@ -6886,7 +6886,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
       __ j(above_equal, &string1);
 
       // First and second argument are strings.
-      __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2);
+      __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1);
 
       // Only first argument is a string.
       __ bind(&string1);
@@ -6954,12 +6954,11 @@ void FloatingPointHelper::AllocateHeapNumber(MacroAssembler* masm,
                               scratch1,
                               scratch2,
                               need_gc,
-                              false);
+                              TAG_OBJECT);
 
-  // Set the map and tag the result.
-  __ mov(Operand(result, HeapObject::kMapOffset),
+  // Set the map.
+  __ mov(FieldOperand(result, HeapObject::kMapOffset),
          Immediate(Factory::heap_number_map()));
-  __ or_(Operand(result), Immediate(kHeapObjectTag));
 }
 
 
@@ -7176,7 +7175,7 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
   __ pop(ebx);  // Return address.
   __ push(edx);
   __ push(ebx);
-  __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
+  __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1);
 }
 
 
@@ -7201,7 +7200,7 @@ void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
 
   // Do the runtime call to allocate the arguments object.
   __ bind(&runtime);
-  __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
+  __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
 }
 
 
@@ -7437,7 +7436,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
   __ push(eax);
 
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
+  __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1);
 }
 
 
@@ -7469,6 +7468,13 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
 }
 
 
+int CEntryStub::MinorKey() {
+  ASSERT(result_size_ <= 2);
+  // Result returned in eax, or eax+edx if result_size_ is 2.
+  return 0;
+}
+
+
 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
   // eax holds the exception.
 
index 4ef0862..7e0dfd1 100644 (file)
@@ -36,9 +36,7 @@ namespace internal {
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 
-// A debug break in the frame exit code is identified by a call instruction.
 bool BreakLocationIterator::IsDebugBreakAtReturn() {
-  // Opcode E8 is call.
   return Debug::IsDebugBreakAtReturn(rinfo());
 }
 
@@ -49,7 +47,7 @@ bool BreakLocationIterator::IsDebugBreakAtReturn() {
 void BreakLocationIterator::SetDebugBreakAtReturn() {
   ASSERT(Debug::kIa32JSReturnSequenceLength >=
          Debug::kIa32CallInstructionLength);
-  rinfo()->PatchCodeWithCall(Debug::debug_break_return_entry()->entry(),
+  rinfo()->PatchCodeWithCall(Debug::debug_break_return()->entry(),
       Debug::kIa32JSReturnSequenceLength - Debug::kIa32CallInstructionLength);
 }
 
@@ -61,11 +59,11 @@ void BreakLocationIterator::ClearDebugBreakAtReturn() {
 }
 
 
-// Check whether the JS frame exit code has been patched with a debug break.
+// A debug break in the frame exit code is identified by the JS frame exit code
+// having been patched with a call instruction.
 bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) {
   ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()));
-  // Opcode E8 is call.
-  return (*(rinfo->pc()) == 0xE8);
+  return rinfo->IsCallInstruction();
 }
 
 
@@ -194,17 +192,6 @@ void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
 }
 
 
-void Debug::GenerateReturnDebugBreakEntry(MacroAssembler* masm) {
-  // OK to clobber ebx as we are returning from a JS function through the code
-  // generated by CodeGenerator::GenerateReturnSequence()
-  ExternalReference debug_break_return =
-      ExternalReference(Debug_Address::DebugBreakReturn());
-  __ mov(ebx, Operand::StaticVariable(debug_break_return));
-  __ add(Operand(ebx), Immediate(Code::kHeaderSize - kHeapObjectTag));
-  __ jmp(Operand(ebx));
-}
-
-
 void Debug::GenerateStubNoRegistersDebugBreak(MacroAssembler* masm) {
   // Register state for stub CallFunction (from CallFunctionStub in ic-ia32.cc).
   // ----------- S t a t e -------------
index e39808b..9a2753d 100644 (file)
@@ -404,7 +404,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
   __ push(eax);
   __ push(ecx);
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
+  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
 
   // Check whether the elements is a pixel array.
   // eax: value
@@ -667,7 +667,7 @@ void CallIC::Generate(MacroAssembler* masm,
   __ push(ebx);
 
   // Call the entry.
-  CEntryStub stub;
+  CEntryStub stub(1);
   __ mov(eax, Immediate(2));
   __ mov(ebx, Immediate(f));
   __ CallStub(&stub);
@@ -799,7 +799,7 @@ void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ push(ebx);  // return address
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 2);
+  __ TailCallRuntime(f, 2, 1);
 }
 
 
@@ -927,7 +927,7 @@ void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ push(ebx);  // return address
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 2);
+  __ TailCallRuntime(f, 2, 1);
 }
 
 
@@ -967,7 +967,7 @@ void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
 
   // Perform tail call to the entry.
   __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
+      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
 }
 
 
@@ -987,7 +987,7 @@ void StoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ push(ebx);
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 3);
+  __ TailCallRuntime(f, 3, 1);
 }
 
 
@@ -1010,7 +1010,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
   __ push(ecx);
 
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(f, 3);
+  __ TailCallRuntime(f, 3, 1);
 }
 
 
@@ -1032,7 +1032,7 @@ void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
 
   // Do tail-call to runtime routine.
   __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
+      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
 }
 
 #undef __
index 754b74a..79b3089 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2006-2009 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -620,18 +620,22 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
 }
 
 
-void MacroAssembler::LoadAllocationTopHelper(
-    Register result,
-    Register result_end,
-    Register scratch,
-    bool result_contains_top_on_entry) {
+void MacroAssembler::LoadAllocationTopHelper(Register result,
+                                             Register result_end,
+                                             Register scratch,
+                                             AllocationFlags flags) {
   ExternalReference new_space_allocation_top =
       ExternalReference::new_space_allocation_top_address();
 
   // Just return if allocation top is already known.
-  if (result_contains_top_on_entry) {
+  if ((flags & RESULT_CONTAINS_TOP) != 0) {
     // No use of scratch if allocation top is provided.
     ASSERT(scratch.is(no_reg));
+#ifdef DEBUG
+    // Assert that result actually contains top on entry.
+    cmp(result, Operand::StaticVariable(new_space_allocation_top));
+    Check(equal, "Unexpected allocation top");
+#endif
     return;
   }
 
@@ -659,20 +663,17 @@ void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
   }
 }
 
-void MacroAssembler::AllocateObjectInNewSpace(
-    int object_size,
-    Register result,
-    Register result_end,
-    Register scratch,
-    Label* gc_required,
-    bool result_contains_top_on_entry) {
+
+void MacroAssembler::AllocateObjectInNewSpace(int object_size,
+                                              Register result,
+                                              Register result_end,
+                                              Register scratch,
+                                              Label* gc_required,
+                                              AllocationFlags flags) {
   ASSERT(!result.is(result_end));
 
   // Load address of new object into result.
-  LoadAllocationTopHelper(result,
-                          result_end,
-                          scratch,
-                          result_contains_top_on_entry);
+  LoadAllocationTopHelper(result, result_end, scratch, flags);
 
   // Calculate new top and bail out if new space is exhausted.
   ExternalReference new_space_allocation_limit =
@@ -683,25 +684,26 @@ void MacroAssembler::AllocateObjectInNewSpace(
 
   // Update allocation top.
   UpdateAllocationTopHelper(result_end, scratch);
+
+  // Tag result if requested.
+  if ((flags & TAG_OBJECT) != 0) {
+    or_(Operand(result), Immediate(kHeapObjectTag));
+  }
 }
 
 
-void MacroAssembler::AllocateObjectInNewSpace(
-    int header_size,
-    ScaleFactor element_size,
-    Register element_count,
-    Register result,
-    Register result_end,
-    Register scratch,
-    Label* gc_required,
-    bool result_contains_top_on_entry) {
+void MacroAssembler::AllocateObjectInNewSpace(int header_size,
+                                              ScaleFactor element_size,
+                                              Register element_count,
+                                              Register result,
+                                              Register result_end,
+                                              Register scratch,
+                                              Label* gc_required,
+                                              AllocationFlags flags) {
   ASSERT(!result.is(result_end));
 
   // Load address of new object into result.
-  LoadAllocationTopHelper(result,
-                          result_end,
-                          scratch,
-                          result_contains_top_on_entry);
+  LoadAllocationTopHelper(result, result_end, scratch, flags);
 
   // Calculate new top and bail out if new space is exhausted.
   ExternalReference new_space_allocation_limit =
@@ -712,24 +714,24 @@ void MacroAssembler::AllocateObjectInNewSpace(
 
   // Update allocation top.
   UpdateAllocationTopHelper(result_end, scratch);
+
+  // Tag result if requested.
+  if ((flags & TAG_OBJECT) != 0) {
+    or_(Operand(result), Immediate(kHeapObjectTag));
+  }
 }
 
 
-void MacroAssembler::AllocateObjectInNewSpace(
-    Register object_size,
-    Register result,
-    Register result_end,
-    Register scratch,
-    Label* gc_required,
-    bool result_contains_top_on_entry) {
+void MacroAssembler::AllocateObjectInNewSpace(Register object_size,
+                                              Register result,
+                                              Register result_end,
+                                              Register scratch,
+                                              Label* gc_required,
+                                              AllocationFlags flags) {
   ASSERT(!result.is(result_end));
 
   // Load address of new object into result.
-  LoadAllocationTopHelper(result,
-                          result_end,
-                          scratch,
-                          result_contains_top_on_entry);
-
+  LoadAllocationTopHelper(result, result_end, scratch, flags);
 
   // Calculate new top and bail out if new space is exhausted.
   ExternalReference new_space_allocation_limit =
@@ -743,6 +745,11 @@ void MacroAssembler::AllocateObjectInNewSpace(
 
   // Update allocation top.
   UpdateAllocationTopHelper(result_end, scratch);
+
+  // Tag result if requested.
+  if ((flags & TAG_OBJECT) != 0) {
+    or_(Operand(result), Immediate(kHeapObjectTag));
+  }
 }
 
 
@@ -889,7 +896,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
 
 
 void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
-                                     int num_arguments) {
+                                     int num_arguments,
+                                     int result_size) {
   // 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
@@ -902,7 +910,7 @@ void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
 void MacroAssembler::JumpToBuiltin(const ExternalReference& ext) {
   // Set the entry point and jump to the C entry runtime stub.
   mov(ebx, Immediate(ext));
-  CEntryStub ces;
+  CEntryStub ces(1);
   jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
 }
 
@@ -1162,8 +1170,9 @@ void MacroAssembler::Abort(const char* msg) {
 }
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 CodePatcher::CodePatcher(byte* address, int size)
-  : address_(address), size_(size), masm_(address, size + Assembler::kGap) {
+    : address_(address), size_(size), masm_(address, size + Assembler::kGap) {
   // Create a new macro assembler pointing to the address of the code to patch.
   // The size is adjusted with kGap on order for the assembler to generate size
   // bytes of instructions without failing with buffer size constraints.
@@ -1179,6 +1188,7 @@ CodePatcher::~CodePatcher() {
   ASSERT(masm_.pc_ == address_ + size_);
   ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
 }
+#endif  // ENABLE_DEBUGGER_SUPPORT
 
 
 } }  // namespace v8::internal
index f10ec16..fa61183 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2006-2009 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -37,25 +37,6 @@ namespace internal {
 class JumpTarget;
 
 
-// Helper types to make flags easier to read at call sites.
-enum InvokeFlag {
-  CALL_FUNCTION,
-  JUMP_FUNCTION
-};
-
-enum CodeLocation {
-  IN_JAVASCRIPT,
-  IN_JS_ENTRY,
-  IN_C_ENTRY
-};
-
-enum HandlerType {
-  TRY_CATCH_HANDLER,
-  TRY_FINALLY_HANDLER,
-  JS_ENTRY_HANDLER
-};
-
-
 // MacroAssembler implements a collection of frequently used macros.
 class MacroAssembler: public Assembler {
  public:
@@ -201,7 +182,7 @@ class MacroAssembler: public Assembler {
                                 Register result_end,
                                 Register scratch,
                                 Label* gc_required,
-                                bool result_contains_top_on_entry);
+                                AllocationFlags flags);
 
   void AllocateObjectInNewSpace(int header_size,
                                 ScaleFactor element_size,
@@ -210,14 +191,14 @@ class MacroAssembler: public Assembler {
                                 Register result_end,
                                 Register scratch,
                                 Label* gc_required,
-                                bool result_contains_top_on_entry);
+                                AllocationFlags flags);
 
   void AllocateObjectInNewSpace(Register object_size,
                                 Register result,
                                 Register result_end,
                                 Register scratch,
                                 Label* gc_required,
-                                bool result_contains_top_on_entry);
+                                AllocationFlags flags);
 
   // Undo allocation in new space. The object passed and objects allocated after
   // it will no longer be allocated. Make sure that no pointers are left to the
@@ -275,7 +256,9 @@ class MacroAssembler: public Assembler {
   // Tail call of a runtime routine (jump).
   // Like JumpToBuiltin, but also takes care of passing the number
   // of arguments.
-  void TailCallRuntime(const ExternalReference& ext, int num_arguments);
+  void TailCallRuntime(const ExternalReference& ext,
+                       int num_arguments,
+                       int result_size);
 
   // Jump to the builtin routine.
   void JumpToBuiltin(const ExternalReference& ext);
@@ -350,11 +333,12 @@ class MacroAssembler: public Assembler {
   void LoadAllocationTopHelper(Register result,
                                Register result_end,
                                Register scratch,
-                               bool result_contains_top_on_entry);
+                               AllocationFlags flags);
   void UpdateAllocationTopHelper(Register result_end, Register scratch);
 };
 
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
 // The code patcher is used to patch (typically) small parts of code e.g. for
 // debugging and other types of instrumentation. When using the code patcher
 // the exact number of bytes specified must be emitted. Is not legal to emit
@@ -373,6 +357,7 @@ class CodePatcher {
   int size_;  // Number of bytes of the expected patch size.
   MacroAssembler masm_;  // Macro assembler used to generate the code.
 };
+#endif  // ENABLE_DEBUGGER_SUPPORT
 
 
 // -----------------------------------------------------------------------------
index 049c57e..58a3ce5 100644 (file)
@@ -302,7 +302,7 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
   __ mov(eax, Immediate(5));
   __ mov(ebx, Immediate(ref));
 
-  CEntryStub stub;
+  CEntryStub stub(1);
   __ CallStub(&stub);
 }
 
@@ -467,7 +467,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
 
       ExternalReference ref =
           ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
-      __ TailCallRuntime(ref, 5);
+      __ TailCallRuntime(ref, 5, 1);
 
       __ bind(&cleanup);
       __ pop(scratch1);
@@ -489,7 +489,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
 
     ExternalReference ref = ExternalReference(
         IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
-    __ TailCallRuntime(ref, 5);
+    __ TailCallRuntime(ref, 5, 1);
   }
 
  private:
@@ -593,7 +593,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
     __ mov(eax, Immediate(5));
     __ mov(ebx, Immediate(ref));
 
-    CEntryStub stub;
+    CEntryStub stub(1);
     __ CallStub(&stub);
 
     __ LeaveInternalFrame();
@@ -789,7 +789,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
   // Do tail-call to the runtime system.
   ExternalReference load_callback_property =
       ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
-  __ TailCallRuntime(load_callback_property, 5);
+  __ TailCallRuntime(load_callback_property, 5, 1);
 }
 
 
@@ -1237,7 +1237,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
   // Do tail-call to the runtime system.
   ExternalReference store_callback_property =
       ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
-  __ TailCallRuntime(store_callback_property, 4);
+  __ TailCallRuntime(store_callback_property, 4, 1);
 
   // Handle store cache miss.
   __ bind(&miss);
@@ -1290,7 +1290,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
   // Do tail-call to the runtime system.
   ExternalReference store_ic_property =
       ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
-  __ TailCallRuntime(store_ic_property, 3);
+  __ TailCallRuntime(store_ic_property, 3, 1);
 
   // Handle store cache miss.
   __ bind(&miss);
@@ -1783,10 +1783,12 @@ Object* ConstructStubCompiler::CompileConstructStub(
   // ebx: initial map
   __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
   __ shl(ecx, kPointerSizeLog2);
-  // Make sure that the maximum heap object size will never cause us
-  // problems here.
-  ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize);
-  __ AllocateObjectInNewSpace(ecx, edx, ecx, no_reg, &generic_stub_call, false);
+  __ AllocateObjectInNewSpace(ecx,
+                              edx,
+                              ecx,
+                              no_reg,
+                              &generic_stub_call,
+                              NO_ALLOCATION_FLAGS);
 
   // Allocated the JSObject, now initialize the fields and add the heap tag.
   // ebx: initial map
index b6c06d8..dd7ea1c 100644 (file)
@@ -62,9 +62,8 @@ class List {
     return data_[i];
   }
   inline T& at(int i) const  { return operator[](i); }
-  inline T& last() const {
-    return at(length_ - 1);
-  }
+  inline T& last() const { return at(length_ - 1); }
+  inline T& first() const { return at(0); }
 
   INLINE(bool is_empty() const) { return length_ == 0; }
   INLINE(int length() const) { return length_; }
index 5680820..6bbefbc 100644 (file)
@@ -890,9 +890,7 @@ void Logger::HeapSampleJSConstructorEvent(const char* constructor,
   if (!Log::IsEnabled() || !FLAG_log_gc) return;
   LogMessageBuilder msg;
   msg.Append("heap-js-cons-item,%s,%d,%d\n",
-             constructor != NULL ?
-                 (constructor[0] != '\0' ? constructor : "(anonymous)") :
-                 "(no_constructor)",
+             constructor[0] != '\0' ? constructor : "(anonymous)",
              number, bytes);
   msg.WriteToLogFile();
 #endif
index 983802e..5631dec 100644 (file)
 #ifndef V8_MACRO_ASSEMBLER_H_
 #define V8_MACRO_ASSEMBLER_H_
 
+
+// Helper types to make boolean flag easier to read at call-site.
+enum InvokeFlag {
+  CALL_FUNCTION,
+  JUMP_FUNCTION
+};
+
+
+enum CodeLocation {
+  IN_JAVASCRIPT,
+  IN_JS_ENTRY,
+  IN_C_ENTRY
+};
+
+
+enum HandlerType {
+  TRY_CATCH_HANDLER,
+  TRY_FINALLY_HANDLER,
+  JS_ENTRY_HANDLER
+};
+
+
+// Flags used for the AllocateObjectInNewSpace functions.
+enum AllocationFlags {
+  // No special flags.
+  NO_ALLOCATION_FLAGS = 0,
+  // Return the pointer to the allocated already tagged as a heap object.
+  TAG_OBJECT = 1 << 0,
+  // The content of the result register already contains the allocation top in
+  // new space.
+  RESULT_CONTAINS_TOP = 1 << 1
+};
+
+
 #if V8_TARGET_ARCH_IA32
 #include "assembler.h"
 #include "ia32/assembler-ia32.h"
index d139093..e682fe2 100644 (file)
@@ -41,6 +41,7 @@ namespace internal {
 
 bool MarkCompactCollector::force_compaction_ = false;
 bool MarkCompactCollector::compacting_collection_ = false;
+bool MarkCompactCollector::compact_on_next_gc_ = false;
 
 int MarkCompactCollector::previous_marked_count_ = 0;
 GCTracer* MarkCompactCollector::tracer_ = NULL;
@@ -104,35 +105,15 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) {
   // variable.
   tracer_ = tracer;
 
-  static const int kFragmentationLimit = 50;  // Percent.
 #ifdef DEBUG
   ASSERT(state_ == IDLE);
   state_ = PREPARE_GC;
 #endif
   ASSERT(!FLAG_always_compact || !FLAG_never_compact);
 
-  compacting_collection_ = FLAG_always_compact || force_compaction_;
-
-  // We compact the old generation if it gets too fragmented (ie, we could
-  // recover an expected amount of space by reclaiming the waste and free
-  // list blocks).  We always compact when the flag --gc-global is true
-  // because objects do not get promoted out of new space on non-compacting
-  // GCs.
-  if (!compacting_collection_) {
-    int old_gen_recoverable = 0;
-    int old_gen_used = 0;
-
-    OldSpaces spaces;
-    while (OldSpace* space = spaces.next()) {
-      old_gen_recoverable += space->Waste() + space->AvailableFree();
-      old_gen_used += space->Size();
-    }
-    int old_gen_fragmentation =
-      static_cast<int>((old_gen_recoverable * 100.0) / old_gen_used);
-    if (old_gen_fragmentation > kFragmentationLimit) {
-      compacting_collection_ = true;
-    }
-  }
+  compacting_collection_ =
+      FLAG_always_compact || force_compaction_ || compact_on_next_gc_;
+  compact_on_next_gc_ = false;
 
   if (FLAG_never_compact) compacting_collection_ = false;
   if (FLAG_collect_maps) CreateBackPointers();
@@ -173,6 +154,31 @@ void MarkCompactCollector::Finish() {
   // GC, because it relies on the new address of certain old space
   // objects (empty string, illegal builtin).
   StubCache::Clear();
+
+  // If we've just compacted old space there's no reason to check the
+  // fragmentation limit. Just return.
+  if (HasCompacted()) return;
+
+  // We compact the old generation on the next GC if it has gotten too
+  // fragmented (ie, we could recover an expected amount of space by
+  // reclaiming the waste and free list blocks).
+  static const int kFragmentationLimit = 15;        // Percent.
+  static const int kFragmentationAllowed = 1 * MB;  // Absolute.
+  int old_gen_recoverable = 0;
+  int old_gen_used = 0;
+
+  OldSpaces spaces;
+  while (OldSpace* space = spaces.next()) {
+    old_gen_recoverable += space->Waste() + space->AvailableFree();
+    old_gen_used += space->Size();
+  }
+
+  int old_gen_fragmentation =
+      static_cast<int>((old_gen_recoverable * 100.0) / old_gen_used);
+  if (old_gen_fragmentation > kFragmentationLimit &&
+      old_gen_recoverable > kFragmentationAllowed) {
+    compact_on_next_gc_ = true;
+  }
 }
 
 
index 0bd212e..2da2b1f 100644 (file)
@@ -130,6 +130,9 @@ class MarkCompactCollector: public AllStatic {
   // Global flag indicating whether spaces were compacted on the last GC.
   static bool compacting_collection_;
 
+  // Global flag indicating whether spaces will be compacted on the next GC.
+  static bool compact_on_next_gc_;
+
   // The number of objects left marked at the end of the last completed full
   // GC (expected to be zero).
   static int previous_marked_count_;
index 76ae75b..ee3dd64 100644 (file)
@@ -201,7 +201,8 @@ PropertyAttribute.DontDelete = DONT_DELETE;
 ScopeType = { Global: 0,
               Local: 1,
               With: 2,
-              Closure: 3 };
+              Closure: 3,
+              Catch: 4 };
 
 
 // Mirror hierarchy:
index ef4aae5..9fc9b1d 100644 (file)
@@ -769,11 +769,14 @@ void JSRegExp::JSRegExpVerify() {
 
       FixedArray* arr = FixedArray::cast(data());
       Object* ascii_data = arr->get(JSRegExp::kIrregexpASCIICodeIndex);
-      ASSERT(ascii_data->IsTheHole()
-          || (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
+      // TheHole : Not compiled yet.
+      // JSObject: Compilation error.
+      // Code/ByteArray: Compiled code.
+      ASSERT(ascii_data->IsTheHole() || ascii_data->IsJSObject() ||
+          (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
       Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
-      ASSERT(uc16_data->IsTheHole()
-          || (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
+      ASSERT(uc16_data->IsTheHole() || ascii_data->IsJSObject() ||
+          (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
       ASSERT(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
       ASSERT(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
       break;
index 9ea131f..583af7c 100644 (file)
@@ -1186,7 +1186,9 @@ void HeapNumber::HeapNumberPrint(StringStream* accumulator) {
 
 
 String* JSObject::class_name() {
-  if (IsJSFunction()) return Heap::function_class_symbol();
+  if (IsJSFunction()) {
+    return Heap::function_class_symbol();
+  }
   if (map()->constructor()->IsJSFunction()) {
     JSFunction* constructor = JSFunction::cast(map()->constructor());
     return String::cast(constructor->shared()->instance_class_name());
@@ -1196,6 +1198,20 @@ String* JSObject::class_name() {
 }
 
 
+String* JSObject::constructor_name() {
+  if (IsJSFunction()) {
+    return Heap::function_class_symbol();
+  }
+  if (map()->constructor()->IsJSFunction()) {
+    JSFunction* constructor = JSFunction::cast(map()->constructor());
+    String* name = String::cast(constructor->shared()->name());
+    return name->length() > 0 ? name : constructor->shared()->inferred_name();
+  }
+  // If the constructor is not present, return "Object".
+  return Heap::Object_symbol();
+}
+
+
 void JSObject::JSObjectIterateBody(int object_size, ObjectVisitor* v) {
   // Iterate over all fields in the body. Assumes all are Object*.
   IteratePointers(v, kPropertiesOffset, object_size);
index 3f6f5ff..d9edce7 100644 (file)
@@ -1392,6 +1392,10 @@ class JSObject: public HeapObject {
   // Returns the class name ([[Class]] property in the specification).
   String* class_name();
 
+  // Returns the constructor name (the name (possibly, inferred name) of the
+  // function that was used to instantiate the object).
+  String* constructor_name();
+
   // Retrieve interceptors.
   InterceptorInfo* GetNamedInterceptor();
   InterceptorInfo* GetIndexedInterceptor();
@@ -2634,8 +2638,8 @@ class Code: public HeapObject {
   // the layout of the code object into account.
   int ExecutableSize() {
     // Check that the assumptions about the layout of the code object holds.
-    ASSERT_EQ(instruction_start() - address(),
-              static_cast<intptr_t>(Code::kHeaderSize));
+    ASSERT_EQ(static_cast<int>(instruction_start() - address()),
+              Code::kHeaderSize);
     return instruction_size() + Code::kHeaderSize;
   }
 
@@ -2891,8 +2895,12 @@ class Map: public HeapObject {
 
   // Byte offsets within kInstanceSizesOffset.
   static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
-  static const int kInObjectPropertiesOffset = kInstanceSizesOffset + 1;
-  static const int kPreAllocatedPropertyFieldsOffset = kInstanceSizesOffset + 2;
+  static const int kInObjectPropertiesByte = 1;
+  static const int kInObjectPropertiesOffset =
+      kInstanceSizesOffset + kInObjectPropertiesByte;
+  static const int kPreAllocatedPropertyFieldsByte = 2;
+  static const int kPreAllocatedPropertyFieldsOffset =
+      kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte;
   // The byte at position 3 is not in use at the moment.
 
   // Byte offsets within kInstanceAttributesOffset attributes.
@@ -3097,9 +3105,7 @@ class SharedFunctionInfo: public HeapObject {
   inline bool is_expression();
   inline void set_is_expression(bool value);
 
-  // Is this function a top-level function. Used for accessing the
-  // caller of functions. Top-level functions (scripts, evals) are
-  // returned as null; see JSFunction::GetCallerAccessor(...).
+  // Is this function a top-level function (scripts, evals).
   inline bool is_toplevel();
   inline void set_is_toplevel(bool value);
 
@@ -3528,9 +3534,13 @@ class JSRegExp: public JSObject {
 
   static const int kAtomDataSize = kAtomPatternIndex + 1;
 
-  // Irregexp compiled code or bytecode for ASCII.
+  // Irregexp compiled code or bytecode for ASCII. If compilation
+  // fails, this fields hold an exception object that should be
+  // thrown if the regexp is used again.
   static const int kIrregexpASCIICodeIndex = kDataIndex;
-  // Irregexp compiled code or bytecode for UC16.
+  // Irregexp compiled code or bytecode for UC16.  If compilation
+  // fails, this fields hold an exception object that should be
+  // thrown if the regexp is used again.
   static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
   // Maximal number of registers used by either ASCII or UC16.
   // Only used to check that there is enough stack space
index 92d72f8..44d283b 100644 (file)
@@ -141,7 +141,9 @@ void* OS::Allocate(const size_t requested,
 
 void OS::Free(void* buf, const size_t length) {
   // TODO(1240712): munmap has a return value which is ignored here.
-  munmap(buf, length);
+  int result = munmap(buf, length);
+  USE(result);
+  ASSERT(result == 0);
 }
 
 
@@ -334,7 +336,7 @@ bool VirtualMemory::Commit(void* address, size_t size, bool executable) {
 
 bool VirtualMemory::Uncommit(void* address, size_t size) {
   return mmap(address, size, PROT_NONE,
-              MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
+              MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED,
               kMmapFd, kMmapFdOffset) != MAP_FAILED;
 }
 
index 6ec5070..fe4c31f 100644 (file)
@@ -56,6 +56,8 @@
 #include "v8.h"
 
 #include "platform.h"
+#include "top.h"
+#include "v8threads.h"
 
 
 namespace v8 {
@@ -145,7 +147,9 @@ void* OS::Allocate(const size_t requested,
 
 void OS::Free(void* address, const size_t size) {
   // TODO(1240712): munmap has a return value which is ignored here.
-  munmap(address, size);
+  int result = munmap(address, size);
+  USE(result);
+  ASSERT(result == 0);
 }
 
 
@@ -360,7 +364,7 @@ bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
 
 bool VirtualMemory::Uncommit(void* address, size_t size) {
   return mmap(address, size, PROT_NONE,
-              MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
+              MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED,
               kMmapFd, kMmapFdOffset) != MAP_FAILED;
 }
 
@@ -580,6 +584,7 @@ Semaphore* OS::CreateSemaphore(int count) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
 
 static Sampler* active_sampler_ = NULL;
+static pthread_t vm_thread_ = 0;
 
 
 #if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__))
@@ -608,6 +613,30 @@ enum ArmRegisters {R15 = 15, R13 = 13, R11 = 11};
 #endif
 
 
+// A function that determines if a signal handler is called in the context
+// of a VM thread.
+//
+// The problem is that SIGPROF signal can be delivered to an arbitrary thread
+// (see http://code.google.com/p/google-perftools/issues/detail?id=106#c2)
+// So, if the signal is being handled in the context of a non-VM thread,
+// it means that the VM thread is running, and trying to sample its stack can
+// cause a crash.
+static inline bool IsVmThread() {
+  // In the case of a single VM thread, this check is enough.
+  if (pthread_equal(pthread_self(), vm_thread_)) return true;
+  // If there are multiple threads that use VM, they must have a thread id
+  // stored in TLS. To verify that the thread is really executing VM,
+  // we check Top's data. Having that ThreadManager::RestoreThread first
+  // restores ThreadLocalTop from TLS, and only then erases the TLS value,
+  // reading Top::thread_id() should not be affected by races.
+  if (ThreadManager::HasId() && !ThreadManager::IsArchived() &&
+      ThreadManager::CurrentId() == Top::thread_id()) {
+    return true;
+  }
+  return false;
+}
+
+
 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
   USE(info);
   if (signal != SIGPROF) return;
@@ -640,7 +669,8 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
     sample.fp = mcontext.arm_fp;
 #endif
 #endif
-    active_sampler_->SampleStack(&sample);
+    if (IsVmThread())
+      active_sampler_->SampleStack(&sample);
   }
 
   // We always sample the VM state.
@@ -678,6 +708,8 @@ void Sampler::Start() {
   // platforms.
   if (active_sampler_ != NULL) return;
 
+  vm_thread_ = pthread_self();
+
   // Request profiling signals.
   struct sigaction sa;
   sa.sa_sigaction = ProfilerSignalHandler;
@@ -713,6 +745,7 @@ void Sampler::Stop() {
   active_ = false;
 }
 
+
 #endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
index c081064..596b0fb 100644 (file)
@@ -141,7 +141,9 @@ void* OS::Allocate(const size_t requested,
 
 void OS::Free(void* address, const size_t size) {
   // TODO(1240712): munmap has a return value which is ignored here.
-  munmap(address, size);
+  int result = munmap(address, size);
+  USE(result);
+  ASSERT(result == 0);
 }
 
 
@@ -211,8 +213,17 @@ void OS::LogSharedLibraryAddresses() {
   for (unsigned int i = 0; i < images_count; ++i) {
     const mach_header* header = _dyld_get_image_header(i);
     if (header == NULL) continue;
+#if V8_HOST_ARCH_X64
+    uint64_t size;
+    char* code_ptr = getsectdatafromheader_64(
+        reinterpret_cast<const mach_header_64*>(header),
+        SEG_TEXT,
+        SECT_TEXT,
+        &size);
+#else
     unsigned int size;
     char* code_ptr = getsectdatafromheader(header, SEG_TEXT, SECT_TEXT, &size);
+#endif
     if (code_ptr == NULL) continue;
     const uintptr_t slide = _dyld_get_image_vmaddr_slide(i);
     const uintptr_t start = reinterpret_cast<uintptr_t>(code_ptr) + slide;
@@ -309,7 +320,7 @@ bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
 
 bool VirtualMemory::Uncommit(void* address, size_t size) {
   return mmap(address, size, PROT_NONE,
-              MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
+              MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED,
               kMmapFd, kMmapFdOffset) != MAP_FAILED;
 }
 
index f772d32..95776e5 100644 (file)
@@ -4556,22 +4556,25 @@ static Object* Runtime_LookupContext(Arguments args) {
 }
 
 
-// A mechanism to return pairs of Object*'s. This is somewhat
-// compiler-dependent as it assumes that a 64-bit value (a long long)
-// is returned via two registers (edx:eax on ia32). Both the ia32 and
-// arm platform support this; it is mostly an issue of "coaxing" the
-// compiler to do the right thing.
-//
-// TODO(1236026): This is a non-portable hack that should be removed.
+// A mechanism to return a pair of Object pointers in registers (if possible).
+// How this is achieved is calling convention-dependent.
+// All currently supported x86 compiles uses calling conventions that are cdecl
+// variants where a 64-bit value is returned in two 32-bit registers
+// (edx:eax on ia32, r1:r0 on ARM).
+// In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
+// In Win64 calling convention, a struct of two pointers is returned in memory,
+// allocated by the caller, and passed as a pointer in a hidden first parameter.
 #ifdef V8_HOST_ARCH_64_BIT
-// Tested with GCC, not with MSVC.
 struct ObjectPair {
   Object* x;
   Object* y;
 };
+
 static inline ObjectPair MakePair(Object* x, Object* y) {
   ObjectPair result = {x, y};
-  return result;  // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
+  // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
+  // In Win64 they are assigned to a hidden first argument.
+  return result;
 }
 #else
 typedef uint64_t ObjectPair;
@@ -4582,8 +4585,6 @@ static inline ObjectPair MakePair(Object* x, Object* y) {
 #endif
 
 
-
-
 static inline Object* Unhole(Object* x, PropertyAttributes attributes) {
   ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
   USE(attributes);
@@ -4612,7 +4613,7 @@ static JSObject* ComputeReceiverForNonGlobal(JSObject* holder) {
 
 static ObjectPair LoadContextSlotHelper(Arguments args, bool throw_error) {
   HandleScope scope;
-  ASSERT(args.length() == 2);
+  ASSERT_EQ(2, args.length());
 
   if (!args[0]->IsContext() || !args[1]->IsString()) {
     return MakePair(Top::ThrowIllegalOperation(), NULL);
@@ -6341,7 +6342,12 @@ class ScopeIterator {
     ScopeTypeGlobal = 0,
     ScopeTypeLocal,
     ScopeTypeWith,
-    ScopeTypeClosure
+    ScopeTypeClosure,
+    // Every catch block contains an implicit with block (its parameter is
+    // a JSContextExtensionObject) that extends current scope with a variable
+    // holding exception object. Such with blocks are treated as scopes of their
+    // own type.
+    ScopeTypeCatch
   };
 
   explicit ScopeIterator(JavaScriptFrame* frame)
@@ -6417,7 +6423,14 @@ class ScopeIterator {
       return ScopeTypeClosure;
     }
     ASSERT(context_->has_extension());
-    ASSERT(!context_->extension()->IsJSContextExtensionObject());
+    // Current scope is either an explicit with statement or a with statement
+    // implicitely generated for a catch block.
+    // If the extension object here is a JSContextExtensionObject then
+    // current with statement is one frome a catch block otherwise it's a
+    // regular with statement.
+    if (context_->extension()->IsJSContextExtensionObject()) {
+      return ScopeTypeCatch;
+    }
     return ScopeTypeWith;
   }
 
@@ -6432,6 +6445,7 @@ class ScopeIterator {
         return MaterializeLocalScope(frame_);
         break;
       case ScopeIterator::ScopeTypeWith:
+      case ScopeIterator::ScopeTypeCatch:
         // Return the with object.
         return Handle<JSObject>(CurrentContext()->extension());
         break;
@@ -6488,6 +6502,14 @@ class ScopeIterator {
         break;
       }
 
+      case ScopeIterator::ScopeTypeCatch: {
+        PrintF("Catch:\n");
+        Handle<JSObject> extension =
+            Handle<JSObject>(CurrentContext()->extension());
+        extension->Print();
+        break;
+      }
+
       case ScopeIterator::ScopeTypeClosure: {
         PrintF("Closure:\n");
         CurrentContext()->Print();
@@ -6799,8 +6821,20 @@ Object* Runtime::FindSharedFunctionInfoInScript(Handle<Script> script,
               target_start_position = start_position;
               target = shared;
             } else {
-              if (target_start_position < start_position &&
-                  shared->end_position() < target->end_position()) {
+              if (target_start_position == start_position &&
+                  shared->end_position() == target->end_position()) {
+                  // If a top-level function contain only one function
+                  // declartion the source for the top-level and the function is
+                  // the same. In that case prefer the non top-level function.
+                if (!shared->is_toplevel()) {
+                  target_start_position = start_position;
+                  target = shared;
+                }
+              } else if (target_start_position <= start_position &&
+                         shared->end_position() <= target->end_position()) {
+                // This containment check includes equality as a function inside
+                // a top-level function can share either start or end position
+                // with the top-level function.
                 target_start_position = start_position;
                 target = shared;
               }
@@ -6912,7 +6946,8 @@ static Object* Runtime_ChangeBreakOnException(Arguments args) {
 // Prepare for stepping
 // args[0]: break id for checking execution state
 // args[1]: step action from the enumeration StepAction
-// args[2]: number of times to perform the step
+// args[2]: number of times to perform the step, for step out it is the number
+//          of frames to step down.
 static Object* Runtime_PrepareStep(Arguments args) {
   HandleScope scope;
   ASSERT(args.length() == 3);
@@ -6939,6 +6974,9 @@ static Object* Runtime_PrepareStep(Arguments args) {
     return Top::Throw(Heap::illegal_argument_symbol());
   }
 
+  // Clear all current stepping setup.
+  Debug::ClearStepping();
+
   // Prepare step.
   Debug::PrepareStep(static_cast<StepAction>(step_action), step_count);
   return Heap::undefined_value();
@@ -7598,7 +7636,7 @@ static Object* Runtime_ListNatives(Arguments args) {
   HandleScope scope;
   Handle<JSArray> result = Factory::NewJSArray(0);
   int index = 0;
-#define ADD_ENTRY(Name, argc)                                                \
+#define ADD_ENTRY(Name, argc, ressize)                                       \
   {                                                                          \
     HandleScope inner;                                                       \
     Handle<String> name =                                                    \
@@ -7634,13 +7672,13 @@ static Object* Runtime_IS_VAR(Arguments args) {
 // ----------------------------------------------------------------------------
 // Implementation of Runtime
 
-#define F(name, nargs)                                                 \
+#define F(name, nargs, ressize)                                           \
   { #name, "RuntimeStub_" #name, FUNCTION_ADDR(Runtime_##name), nargs, \
-    static_cast<int>(Runtime::k##name) },
+    static_cast<int>(Runtime::k##name), ressize },
 
 static Runtime::Function Runtime_functions[] = {
   RUNTIME_FUNCTION_LIST(F)
-  { NULL, NULL, NULL, 0, -1 }
+  { NULL, NULL, NULL, 0, -1, 0 }
 };
 
 #undef F
index 1be677a..ca38baf 100644 (file)
@@ -43,269 +43,269 @@ namespace internal {
 // this problem. Please avoid large recursive macros whenever possible.
 #define RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
   /* Property access */ \
-  F(GetProperty, 2) \
-  F(KeyedGetProperty, 2) \
-  F(DeleteProperty, 2) \
-  F(HasLocalProperty, 2) \
-  F(HasProperty, 2) \
-  F(HasElement, 2) \
-  F(IsPropertyEnumerable, 2) \
-  F(GetPropertyNames, 1) \
-  F(GetPropertyNamesFast, 1) \
-  F(GetArgumentsProperty, 1) \
-  F(ToFastProperties, 1) \
-  F(ToSlowProperties, 1) \
-  \
-  F(IsInPrototypeChain, 2) \
-  F(SetHiddenPrototype, 2) \
-  \
-  F(IsConstructCall, 0) \
+  F(GetProperty, 2, 1) \
+  F(KeyedGetProperty, 2, 1) \
+  F(DeleteProperty, 2, 1) \
+  F(HasLocalProperty, 2, 1) \
+  F(HasProperty, 2, 1) \
+  F(HasElement, 2, 1) \
+  F(IsPropertyEnumerable, 2, 1) \
+  F(GetPropertyNames, 1, 1) \
+  F(GetPropertyNamesFast, 1, 1) \
+  F(GetArgumentsProperty, 1, 1) \
+  F(ToFastProperties, 1, 1) \
+  F(ToSlowProperties, 1, 1) \
+  \
+  F(IsInPrototypeChain, 2, 1) \
+  F(SetHiddenPrototype, 2, 1) \
+  \
+  F(IsConstructCall, 0, 1) \
   \
   /* Utilities */ \
-  F(GetCalledFunction, 0) \
-  F(GetFunctionDelegate, 1) \
-  F(GetConstructorDelegate, 1) \
-  F(NewArguments, 1) \
-  F(NewArgumentsFast, 3) \
-  F(LazyCompile, 1) \
-  F(SetNewFunctionAttributes, 1) \
+  F(GetCalledFunction, 0, 1) \
+  F(GetFunctionDelegate, 1, 1) \
+  F(GetConstructorDelegate, 1, 1) \
+  F(NewArguments, 1, 1) \
+  F(NewArgumentsFast, 3, 1) \
+  F(LazyCompile, 1, 1) \
+  F(SetNewFunctionAttributes, 1, 1) \
   \
   /* Array join support */ \
-  F(PushIfAbsent, 2) \
-  F(ArrayConcat, 1) \
+  F(PushIfAbsent, 2, 1) \
+  F(ArrayConcat, 1, 1) \
   \
   /* Conversions */ \
-  F(ToBool, 1) \
-  F(Typeof, 1) \
-  \
-  F(StringToNumber, 1) \
-  F(StringFromCharCodeArray, 1) \
-  F(StringParseInt, 2) \
-  F(StringParseFloat, 1) \
-  F(StringToLowerCase, 1) \
-  F(StringToUpperCase, 1) \
-  F(CharFromCode, 1) \
-  F(URIEscape, 1) \
-  F(URIUnescape, 1) \
-  \
-  F(NumberToString, 1) \
-  F(NumberToInteger, 1) \
-  F(NumberToJSUint32, 1) \
-  F(NumberToJSInt32, 1) \
-  F(NumberToSmi, 1) \
+  F(ToBool, 1, 1) \
+  F(Typeof, 1, 1) \
+  \
+  F(StringToNumber, 1, 1) \
+  F(StringFromCharCodeArray, 1, 1) \
+  F(StringParseInt, 2, 1) \
+  F(StringParseFloat, 1, 1) \
+  F(StringToLowerCase, 1, 1) \
+  F(StringToUpperCase, 1, 1) \
+  F(CharFromCode, 1, 1) \
+  F(URIEscape, 1, 1) \
+  F(URIUnescape, 1, 1) \
+  \
+  F(NumberToString, 1, 1) \
+  F(NumberToInteger, 1, 1) \
+  F(NumberToJSUint32, 1, 1) \
+  F(NumberToJSInt32, 1, 1) \
+  F(NumberToSmi, 1, 1) \
   \
   /* Arithmetic operations */ \
-  F(NumberAdd, 2) \
-  F(NumberSub, 2) \
-  F(NumberMul, 2) \
-  F(NumberDiv, 2) \
-  F(NumberMod, 2) \
-  F(NumberUnaryMinus, 1) \
+  F(NumberAdd, 2, 1) \
+  F(NumberSub, 2, 1) \
+  F(NumberMul, 2, 1) \
+  F(NumberDiv, 2, 1) \
+  F(NumberMod, 2, 1) \
+  F(NumberUnaryMinus, 1, 1) \
   \
-  F(StringAdd, 2) \
-  F(StringBuilderConcat, 2) \
+  F(StringAdd, 2, 1) \
+  F(StringBuilderConcat, 2, 1) \
   \
   /* Bit operations */ \
-  F(NumberOr, 2) \
-  F(NumberAnd, 2) \
-  F(NumberXor, 2) \
-  F(NumberNot, 1) \
+  F(NumberOr, 2, 1) \
+  F(NumberAnd, 2, 1) \
+  F(NumberXor, 2, 1) \
+  F(NumberNot, 1, 1) \
   \
-  F(NumberShl, 2) \
-  F(NumberShr, 2) \
-  F(NumberSar, 2) \
+  F(NumberShl, 2, 1) \
+  F(NumberShr, 2, 1) \
+  F(NumberSar, 2, 1) \
   \
   /* Comparisons */ \
-  F(NumberEquals, 2) \
-  F(StringEquals, 2) \
+  F(NumberEquals, 2, 1) \
+  F(StringEquals, 2, 1) \
   \
-  F(NumberCompare, 3) \
-  F(SmiLexicographicCompare, 2) \
-  F(StringCompare, 2) \
+  F(NumberCompare, 3, 1) \
+  F(SmiLexicographicCompare, 2, 1) \
+  F(StringCompare, 2, 1) \
   \
   /* Math */ \
-  F(Math_abs, 1) \
-  F(Math_acos, 1) \
-  F(Math_asin, 1) \
-  F(Math_atan, 1) \
-  F(Math_atan2, 2) \
-  F(Math_ceil, 1) \
-  F(Math_cos, 1) \
-  F(Math_exp, 1) \
-  F(Math_floor, 1) \
-  F(Math_log, 1) \
-  F(Math_pow, 2) \
-  F(Math_round, 1) \
-  F(Math_sin, 1) \
-  F(Math_sqrt, 1) \
-  F(Math_tan, 1) \
+  F(Math_abs, 1, 1) \
+  F(Math_acos, 1, 1) \
+  F(Math_asin, 1, 1) \
+  F(Math_atan, 1, 1) \
+  F(Math_atan2, 2, 1) \
+  F(Math_ceil, 1, 1) \
+  F(Math_cos, 1, 1) \
+  F(Math_exp, 1, 1) \
+  F(Math_floor, 1, 1) \
+  F(Math_log, 1, 1) \
+  F(Math_pow, 2, 1) \
+  F(Math_round, 1, 1) \
+  F(Math_sin, 1, 1) \
+  F(Math_sqrt, 1, 1) \
+  F(Math_tan, 1, 1) \
   \
   /* Regular expressions */ \
-  F(RegExpCompile, 3) \
-  F(RegExpExec, 4) \
+  F(RegExpCompile, 3, 1) \
+  F(RegExpExec, 4, 1) \
   \
   /* Strings */ \
-  F(StringCharCodeAt, 2) \
-  F(StringIndexOf, 3) \
-  F(StringLastIndexOf, 3) \
-  F(StringLocaleCompare, 2) \
-  F(StringSlice, 3) \
-  F(StringReplaceRegExpWithString, 4) \
-  F(StringMatch, 3) \
+  F(StringCharCodeAt, 2, 1) \
+  F(StringIndexOf, 3, 1) \
+  F(StringLastIndexOf, 3, 1) \
+  F(StringLocaleCompare, 2, 1) \
+  F(StringSlice, 3, 1) \
+  F(StringReplaceRegExpWithString, 4, 1) \
+  F(StringMatch, 3, 1) \
   \
   /* Numbers */ \
-  F(NumberToRadixString, 2) \
-  F(NumberToFixed, 2) \
-  F(NumberToExponential, 2) \
-  F(NumberToPrecision, 2)
+  F(NumberToRadixString, 2, 1) \
+  F(NumberToFixed, 2, 1) \
+  F(NumberToExponential, 2, 1) \
+  F(NumberToPrecision, 2, 1)
 
 #define RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
   /* Reflection */ \
-  F(FunctionSetInstanceClassName, 2) \
-  F(FunctionSetLength, 2) \
-  F(FunctionSetPrototype, 2) \
-  F(FunctionGetName, 1) \
-  F(FunctionSetName, 2) \
-  F(FunctionGetSourceCode, 1) \
-  F(FunctionGetScript, 1) \
-  F(FunctionGetScriptSourcePosition, 1) \
-  F(FunctionGetPositionForOffset, 2) \
-  F(FunctionIsAPIFunction, 1) \
-  F(GetScript, 1) \
-  F(CollectStackTrace, 2) \
-  \
-  F(ClassOf, 1) \
-  F(SetCode, 2) \
-  \
-  F(CreateApiFunction, 1) \
-  F(IsTemplate, 1) \
-  F(GetTemplateField, 2) \
-  F(DisableAccessChecks, 1) \
-  F(EnableAccessChecks, 1) \
+  F(FunctionSetInstanceClassName, 2, 1) \
+  F(FunctionSetLength, 2, 1) \
+  F(FunctionSetPrototype, 2, 1) \
+  F(FunctionGetName, 1, 1) \
+  F(FunctionSetName, 2, 1) \
+  F(FunctionGetSourceCode, 1, 1) \
+  F(FunctionGetScript, 1, 1) \
+  F(FunctionGetScriptSourcePosition, 1, 1) \
+  F(FunctionGetPositionForOffset, 2, 1) \
+  F(FunctionIsAPIFunction, 1, 1) \
+  F(GetScript, 1, 1) \
+  F(CollectStackTrace, 2, 1) \
+  \
+  F(ClassOf, 1, 1) \
+  F(SetCode, 2, 1) \
+  \
+  F(CreateApiFunction, 1, 1) \
+  F(IsTemplate, 1, 1) \
+  F(GetTemplateField, 2, 1) \
+  F(DisableAccessChecks, 1, 1) \
+  F(EnableAccessChecks, 1, 1) \
   \
   /* Dates */ \
-  F(DateCurrentTime, 0) \
-  F(DateParseString, 2) \
-  F(DateLocalTimezone, 1) \
-  F(DateLocalTimeOffset, 0) \
-  F(DateDaylightSavingsOffset, 1) \
+  F(DateCurrentTime, 0, 1) \
+  F(DateParseString, 2, 1) \
+  F(DateLocalTimezone, 1, 1) \
+  F(DateLocalTimeOffset, 0, 1) \
+  F(DateDaylightSavingsOffset, 1, 1) \
   \
   /* Numbers */ \
-  F(NumberIsFinite, 1) \
+  F(NumberIsFinite, 1, 1) \
   \
   /* Globals */ \
-  F(CompileString, 2) \
-  F(GlobalPrint, 1) \
+  F(CompileString, 2, 1) \
+  F(GlobalPrint, 1, 1) \
   \
   /* Eval */ \
-  F(GlobalReceiver, 1) \
-  F(ResolvePossiblyDirectEval, 2) \
+  F(GlobalReceiver, 1, 1) \
+  F(ResolvePossiblyDirectEval, 2, 1) \
   \
-  F(SetProperty, -1 /* 3 or 4 */) \
-  F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */) \
+  F(SetProperty, -1 /* 3 or 4 */, 1) \
+  F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */, 1) \
   \
   /* Arrays */ \
-  F(RemoveArrayHoles, 2) \
-  F(GetArrayKeys, 2) \
-  F(MoveArrayContents, 2) \
-  F(EstimateNumberOfElements, 1) \
+  F(RemoveArrayHoles, 2, 1) \
+  F(GetArrayKeys, 2, 1) \
+  F(MoveArrayContents, 2, 1) \
+  F(EstimateNumberOfElements, 1, 1) \
   \
   /* Getters and Setters */ \
-  F(DefineAccessor, -1 /* 4 or 5 */) \
-  F(LookupAccessor, 3) \
+  F(DefineAccessor, -1 /* 4 or 5 */, 1) \
+  F(LookupAccessor, 3, 1) \
   \
   /* Literals */ \
-  F(MaterializeRegExpLiteral, 4)\
-  F(CreateArrayLiteralBoilerplate, 3) \
-  F(CreateObjectLiteralBoilerplate, 3) \
-  F(CloneLiteralBoilerplate, 1) \
-  F(CloneShallowLiteralBoilerplate, 1) \
+  F(MaterializeRegExpLiteral, 4, 1)\
+  F(CreateArrayLiteralBoilerplate, 3, 1) \
+  F(CreateObjectLiteralBoilerplate, 3, 1) \
+  F(CloneLiteralBoilerplate, 1, 1) \
+  F(CloneShallowLiteralBoilerplate, 1, 1) \
   \
   /* Catch context extension objects */ \
-  F(CreateCatchExtensionObject, 2) \
+  F(CreateCatchExtensionObject, 2, 1) \
   \
   /* Statements */ \
-  F(NewClosure, 2) \
-  F(NewObject, 1) \
-  F(Throw, 1) \
-  F(ReThrow, 1) \
-  F(ThrowReferenceError, 1) \
-  F(StackGuard, 1) \
+  F(NewClosure, 2, 1) \
+  F(NewObject, 1, 1) \
+  F(Throw, 1, 1) \
+  F(ReThrow, 1, 1) \
+  F(ThrowReferenceError, 1, 1) \
+  F(StackGuard, 1, 1) \
   \
   /* Contexts */ \
-  F(NewContext, 1) \
-  F(PushContext, 1) \
-  F(PushCatchContext, 1) \
-  F(LookupContext, 2) \
-  F(LoadContextSlot, 2) \
-  F(LoadContextSlotNoReferenceError, 2) \
-  F(StoreContextSlot, 3) \
+  F(NewContext, 1, 1) \
+  F(PushContext, 1, 1) \
+  F(PushCatchContext, 1, 1) \
+  F(LookupContext, 2, 1) \
+  F(LoadContextSlot, 2, 2) \
+  F(LoadContextSlotNoReferenceError, 2, 2) \
+  F(StoreContextSlot, 3, 1) \
   \
   /* Declarations and initialization */ \
-  F(DeclareGlobals, 3) \
-  F(DeclareContextSlot, 4) \
-  F(InitializeVarGlobal, -1 /* 1 or 2 */) \
-  F(InitializeConstGlobal, 2) \
-  F(InitializeConstContextSlot, 3) \
-  F(OptimizeObjectForAddingMultipleProperties, 2) \
-  F(TransformToFastProperties, 1) \
+  F(DeclareGlobals, 3, 1) \
+  F(DeclareContextSlot, 4, 1) \
+  F(InitializeVarGlobal, -1 /* 1 or 2 */, 1) \
+  F(InitializeConstGlobal, 2, 1) \
+  F(InitializeConstContextSlot, 3, 1) \
+  F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
+  F(TransformToFastProperties, 1, 1) \
   \
   /* Debugging */ \
-  F(DebugPrint, 1) \
-  F(DebugTrace, 0) \
-  F(TraceEnter, 0) \
-  F(TraceExit, 1) \
-  F(Abort, 2) \
+  F(DebugPrint, 1, 1) \
+  F(DebugTrace, 0, 1) \
+  F(TraceEnter, 0, 1) \
+  F(TraceExit, 1, 1) \
+  F(Abort, 2, 1) \
   /* Logging */ \
-  F(Log, 2) \
+  F(Log, 2, 1) \
   \
   /* Pseudo functions - handled as macros by parser */ \
-  F(IS_VAR, 1)
+  F(IS_VAR, 1, 1)
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 #define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
   /* Debugger support*/ \
-  F(DebugBreak, 0) \
-  F(SetDebugEventListener, 2) \
-  F(Break, 0) \
-  F(DebugGetPropertyDetails, 2) \
-  F(DebugGetProperty, 2) \
-  F(DebugLocalPropertyNames, 1) \
-  F(DebugLocalElementNames, 1) \
-  F(DebugPropertyTypeFromDetails, 1) \
-  F(DebugPropertyAttributesFromDetails, 1) \
-  F(DebugPropertyIndexFromDetails, 1) \
-  F(DebugInterceptorInfo, 1) \
-  F(DebugNamedInterceptorPropertyNames, 1) \
-  F(DebugIndexedInterceptorElementNames, 1) \
-  F(DebugNamedInterceptorPropertyValue, 2) \
-  F(DebugIndexedInterceptorElementValue, 2) \
-  F(CheckExecutionState, 1) \
-  F(GetFrameCount, 1) \
-  F(GetFrameDetails, 2) \
-  F(GetScopeCount, 2) \
-  F(GetScopeDetails, 3) \
-  F(DebugPrintScopes, 0) \
-  F(GetCFrames, 1) \
-  F(GetThreadCount, 1) \
-  F(GetThreadDetails, 2) \
-  F(GetBreakLocations, 1) \
-  F(SetFunctionBreakPoint, 3) \
-  F(SetScriptBreakPoint, 3) \
-  F(ClearBreakPoint, 1) \
-  F(ChangeBreakOnException, 2) \
-  F(PrepareStep, 3) \
-  F(ClearStepping, 0) \
-  F(DebugEvaluate, 4) \
-  F(DebugEvaluateGlobal, 3) \
-  F(DebugGetLoadedScripts, 0) \
-  F(DebugReferencedBy, 3) \
-  F(DebugConstructedBy, 2) \
-  F(DebugGetPrototype, 1) \
-  F(SystemBreak, 0) \
-  F(DebugDisassembleFunction, 1) \
-  F(DebugDisassembleConstructor, 1) \
-  F(FunctionGetInferredName, 1)
+  F(DebugBreak, 0, 1) \
+  F(SetDebugEventListener, 2, 1) \
+  F(Break, 0, 1) \
+  F(DebugGetPropertyDetails, 2, 1) \
+  F(DebugGetProperty, 2, 1) \
+  F(DebugLocalPropertyNames, 1, 1) \
+  F(DebugLocalElementNames, 1, 1) \
+  F(DebugPropertyTypeFromDetails, 1, 1) \
+  F(DebugPropertyAttributesFromDetails, 1, 1) \
+  F(DebugPropertyIndexFromDetails, 1, 1) \
+  F(DebugInterceptorInfo, 1, 1) \
+  F(DebugNamedInterceptorPropertyNames, 1, 1) \
+  F(DebugIndexedInterceptorElementNames, 1, 1) \
+  F(DebugNamedInterceptorPropertyValue, 2, 1) \
+  F(DebugIndexedInterceptorElementValue, 2, 1) \
+  F(CheckExecutionState, 1, 1) \
+  F(GetFrameCount, 1, 1) \
+  F(GetFrameDetails, 2, 1) \
+  F(GetScopeCount, 2, 1) \
+  F(GetScopeDetails, 3, 1) \
+  F(DebugPrintScopes, 0, 1) \
+  F(GetCFrames, 1, 1) \
+  F(GetThreadCount, 1, 1) \
+  F(GetThreadDetails, 2, 1) \
+  F(GetBreakLocations, 1, 1) \
+  F(SetFunctionBreakPoint, 3, 1) \
+  F(SetScriptBreakPoint, 3, 1) \
+  F(ClearBreakPoint, 1, 1) \
+  F(ChangeBreakOnException, 2, 1) \
+  F(PrepareStep, 3, 1) \
+  F(ClearStepping, 0, 1) \
+  F(DebugEvaluate, 4, 1) \
+  F(DebugEvaluateGlobal, 3, 1) \
+  F(DebugGetLoadedScripts, 0, 1) \
+  F(DebugReferencedBy, 3, 1) \
+  F(DebugConstructedBy, 2, 1) \
+  F(DebugGetPrototype, 1, 1) \
+  F(SystemBreak, 0, 1) \
+  F(DebugDisassembleFunction, 1, 1) \
+  F(DebugDisassembleConstructor, 1, 1) \
+  F(FunctionGetInferredName, 1, 1)
 #else
 #define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
 #endif
@@ -313,7 +313,7 @@ namespace internal {
 #ifdef DEBUG
 #define RUNTIME_FUNCTION_LIST_DEBUG(F) \
   /* Testing */ \
-  F(ListNatives, 0)
+  F(ListNatives, 0, 1)
 #else
 #define RUNTIME_FUNCTION_LIST_DEBUG(F)
 #endif
@@ -336,7 +336,7 @@ namespace internal {
 class Runtime : public AllStatic {
  public:
   enum FunctionId {
-#define F(name, nargs) k##name,
+#define F(name, nargs, ressize) k##name,
     RUNTIME_FUNCTION_LIST(F)
     kNofFunctions
 #undef F
@@ -357,6 +357,9 @@ class Runtime : public AllStatic {
     // arguments.
     int nargs;
     int stub_id;
+    // Size of result, if complex (larger than a single pointer),
+    // otherwise zero.
+    int result_size;
   };
 
   // Get the runtime function with the given function id.
index a16032a..c894762 100644 (file)
@@ -70,7 +70,7 @@ const int kPageAndOffsetMask = (1 << kPageAndOffsetBits) - 1;
 
 // These values are special allocation space tags used for
 // serialization.
-// Mar the pages executable on platforms that support it.
+// Mark the pages executable on platforms that support it.
 const int kLargeCode = LAST_SPACE + 1;
 // Allocate extra remembered-set bits.
 const int kLargeFixedArray = LAST_SPACE + 2;
@@ -541,7 +541,7 @@ void ExternalReferenceTable::PopulateTable() {
 #undef DEF_ENTRY_A
 
   // Runtime functions
-#define RUNTIME_ENTRY(name, nargs) \
+#define RUNTIME_ENTRY(name, nargs, ressize) \
   { RUNTIME_FUNCTION, \
     Runtime::k##name, \
     "Runtime::" #name },
@@ -1201,19 +1201,25 @@ void Serializer::PutGlobalHandleStack(const List<Handle<Object> >& stack) {
 
 
 void Serializer::PutContextStack() {
-  List<Handle<Object> > contexts(2);
+  List<Context*> contexts(2);
   while (HandleScopeImplementer::instance()->HasSavedContexts()) {
-    Handle<Object> context =
+    Context* context =
       HandleScopeImplementer::instance()->RestoreContext();
     contexts.Add(context);
   }
   for (int i = contexts.length() - 1; i >= 0; i--) {
     HandleScopeImplementer::instance()->SaveContext(contexts[i]);
   }
-  PutGlobalHandleStack(contexts);
+  writer_->PutC('C');
+  writer_->PutC('[');
+  writer_->PutInt(contexts.length());
+  if (!contexts.is_empty()) {
+    Object** start = reinterpret_cast<Object**>(&contexts.first());
+    VisitPointers(start, start + contexts.length());
+  }
+  writer_->PutC(']');
 }
 
-
 void Serializer::PutEncodedAddress(Address addr) {
   writer_->PutC('P');
   writer_->PutAddress(addr);
@@ -1541,9 +1547,16 @@ void Deserializer::GetGlobalHandleStack(List<Handle<Object> >* stack) {
 
 
 void Deserializer::GetContextStack() {
-  List<Handle<Object> > entered_contexts(2);
-  GetGlobalHandleStack(&entered_contexts);
-  for (int i = 0; i < entered_contexts.length(); i++) {
+  reader_.ExpectC('C');
+  CHECK_EQ(reader_.GetC(), '[');
+  int count = reader_.GetInt();
+  List<Context*> entered_contexts(count);
+  if (count > 0) {
+    Object** start = reinterpret_cast<Object**>(&entered_contexts.first());
+    VisitPointers(start, start + count);
+  }
+  reader_.ExpectC(']');
+  for (int i = 0; i < count; i++) {
     HandleScopeImplementer::instance()->SaveContext(entered_contexts[i]);
   }
 }
index 1b24065..f5780ae 100644 (file)
@@ -197,7 +197,7 @@ class Serializer: public ObjectVisitor {
 
   int flags_end_;  // The position right after the flags.
 
-  // An array of per-space SimulatedHeapSpacees used as memory allocators.
+  // An array of per-space SimulatedHeapSpaces used as memory allocators.
   SimulatedHeapSpace* allocator_[LAST_SPACE+1];
   // A list of global handles at serialization time.
   List<Object**> global_handles_;
index 45e82f4..de9b233 100644 (file)
@@ -2561,10 +2561,12 @@ void LargeObjectSpace::Verify() {
     ASSERT(map->IsMap());
     ASSERT(Heap::map_space()->Contains(map));
 
-    // We have only code, sequential strings, fixed arrays, and byte arrays
-    // in large object space.
-    ASSERT(object->IsCode() || object->IsSeqString()
-           || object->IsFixedArray() || object->IsByteArray());
+    // We have only code, sequential strings, external strings
+    // (sequential strings that have been morphed into external
+    // strings), fixed arrays, and byte arrays in large object space.
+    ASSERT(object->IsCode() || object->IsSeqString() ||
+           object->IsExternalString() || object->IsFixedArray() ||
+           object->IsByteArray());
 
     // The object itself should look OK.
     object->Verify();
index 98663db..babdd3f 100644 (file)
@@ -445,12 +445,12 @@ class MemoryAllocator : public AllStatic {
 
   // Due to encoding limitation, we can only have 8K chunks.
   static const int kMaxNofChunks = 1 << Page::kPageSizeBits;
-  // If a chunk has at least 32 pages, the maximum heap size is about
-  // 8 * 1024 * 32 * 8K = 2G bytes.
-#if defined(ANDROID)
-  static const int kPagesPerChunk = 16;
+  // If a chunk has at least 16 pages, the maximum heap size is about
+  // 8K * 8K * 16 = 1G bytes.
+#ifdef V8_TARGET_ARCH_X64
+  static const int kPagesPerChunk = 32;
 #else
-  static const int kPagesPerChunk = 64;
+  static const int kPagesPerChunk = 16;
 #endif
   static const int kChunkSize = kPagesPerChunk * Page::kPageSize;
 
index 8e0a8be..3022a7e 100644 (file)
@@ -241,7 +241,10 @@ ThreadState* ThreadState::Next() {
 }
 
 
-int ThreadManager::next_id_ = 0;
+// Thread ids must start with 1, because in TLS having thread id 0 can't
+// be distinguished from not having a thread id at all (since NULL is
+// defined as 0.)
+int ThreadManager::last_id_ = 0;
 Mutex* ThreadManager::mutex_ = OS::CreateMutex();
 ThreadHandle ThreadManager::mutex_owner_(ThreadHandle::INVALID);
 ThreadHandle ThreadManager::lazily_archived_thread_(ThreadHandle::INVALID);
@@ -250,7 +253,7 @@ ThreadState* ThreadManager::lazily_archived_thread_state_ = NULL;
 
 void ThreadManager::ArchiveThread() {
   ASSERT(!lazily_archived_thread_.IsValid());
-  ASSERT(Thread::GetThreadLocal(thread_state_key) == NULL);
+  ASSERT(!IsArchived());
   ThreadState* state = ThreadState::GetFree();
   state->Unlink();
   Thread::SetThreadLocal(thread_state_key, reinterpret_cast<void*>(state));
@@ -281,6 +284,11 @@ void ThreadManager::EagerlyArchiveThread() {
 }
 
 
+bool ThreadManager::IsArchived() {
+  return Thread::HasThreadLocal(thread_state_key);
+}
+
+
 void ThreadManager::Iterate(ObjectVisitor* v) {
   // Expecting no threads during serialization/deserialization
   for (ThreadState* state = ThreadState::FirstInUse();
@@ -321,15 +329,21 @@ int ThreadManager::CurrentId() {
 
 
 void ThreadManager::AssignId() {
-  if (!Thread::HasThreadLocal(thread_id_key)) {
+  if (!HasId()) {
     ASSERT(Locker::IsLocked());
-    int thread_id = next_id_++;
+    int thread_id = ++last_id_;
+    ASSERT(thread_id > 0);  // see the comment near last_id_ definition.
     Thread::SetThreadLocalInt(thread_id_key, thread_id);
     Top::set_thread_id(thread_id);
   }
 }
 
 
+bool ThreadManager::HasId() {
+  return Thread::HasThreadLocal(thread_id_key);
+}
+
+
 void ThreadManager::TerminateExecution(int thread_id) {
   for (ThreadState* state = ThreadState::FirstInUse();
        state != NULL;
index 3f81f57..f808e54 100644 (file)
@@ -86,6 +86,7 @@ class ThreadManager : public AllStatic {
 
   static void ArchiveThread();
   static bool RestoreThread();
+  static bool IsArchived();
 
   static void Iterate(ObjectVisitor* v);
   static void MarkCompactPrologue(bool is_compacting);
@@ -94,6 +95,7 @@ class ThreadManager : public AllStatic {
 
   static int CurrentId();
   static void AssignId();
+  static bool HasId();
 
   static void TerminateExecution(int thread_id);
 
@@ -101,7 +103,7 @@ class ThreadManager : public AllStatic {
  private:
   static void EagerlyArchiveThread();
 
-  static int next_id_;  // V8 threads are identified through an integer.
+  static int last_id_;  // V8 threads are identified through an integer.
   static Mutex* mutex_;
   static ThreadHandle mutex_owner_;
   static ThreadHandle lazily_archived_thread_;
index 39d18fd..df5058a 100644 (file)
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     1
 #define MINOR_VERSION     3
-#define BUILD_NUMBER      9
+#define BUILD_NUMBER      10
 #define PATCH_LEVEL       0
 #define CANDIDATE_VERSION false
 
index 6304324..af98ef9 100644 (file)
@@ -174,6 +174,7 @@ void CpuFeatures::Probe()  {
 // Additional guard int3 instructions can be added if required.
 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
   // Call instruction takes up 13 bytes and int3 takes up one byte.
+  static const int kCallInstructionSize = 13;
   Address patch_site = pc_;
   Memory::uint16_at(patch_site) = 0xBA49u;  // movq r10, imm64
   // Write "0x00, call r10" starting at last byte of address.  We overwrite
@@ -183,8 +184,11 @@ void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
 
   // Add the requested number of int3 instructions after the call.
   for (int i = 0; i < guard_bytes; i++) {
-    *(patch_site + 13 + i) = 0xCC;  // int3
+    *(patch_site + kCallInstructionSize + i) = 0xCC;  // int3
   }
+
+  // Indicate that code has changed.
+  CPU::FlushICache(patch_site, kCallInstructionSize + guard_bytes);
 }
 
 
@@ -275,7 +279,7 @@ Assembler::Assembler(void* buffer, int buffer_size) {
 
   // Clear the buffer in debug mode unless it was provided by the
   // caller in which case we can't be sure it's okay to overwrite
-  // existing code in it; see CodePatcher::CodePatcher(...).
+  // existing code in it.
 #ifdef DEBUG
   if (own_buffer_) {
     memset(buffer_, 0xCC, buffer_size);  // int3
index 44d8b46..1fea61e 100644 (file)
@@ -44,7 +44,7 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
   // rax, but JumpToBuiltin expects rax to contain the number of
   // arguments including the receiver.
   __ incq(rax);
-  __ JumpToBuiltin(ExternalReference(id));
+  __ JumpToBuiltin(ExternalReference(id), 1);
 }
 
 
@@ -536,11 +536,12 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
     __ movzxbq(rdi, FieldOperand(rax, Map::kInstanceSizeOffset));
     __ shl(rdi, Immediate(kPointerSizeLog2));
     // rdi: size of new object
-    // Make sure that the maximum heap object size will never cause us
-    // problem here, because it is always greater than the maximum
-    // instance size that can be represented in a byte.
-    ASSERT(Heap::MaxObjectSizeInPagedSpace() >= (1 << kBitsPerByte));
-    __ AllocateObjectInNewSpace(rdi, rbx, rdi, no_reg, &rt_call, false);
+    __ AllocateObjectInNewSpace(rdi,
+                                rbx,
+                                rdi,
+                                no_reg,
+                                &rt_call,
+                                NO_ALLOCATION_FLAGS);
     // Allocated the JSObject, now initialize the fields.
     // rax: initial map
     // rbx: JSObject (not HeapObject tagged - the actual address).
@@ -595,8 +596,6 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
     // rbx: JSObject
     // rdi: start of next object (will be start of FixedArray)
     // rdx: number of elements in properties array
-    ASSERT(Heap::MaxObjectSizeInPagedSpace() >
-           (FixedArray::kHeaderSize + 255*kPointerSize));
     __ AllocateObjectInNewSpace(FixedArray::kHeaderSize,
                                 times_pointer_size,
                                 rdx,
@@ -604,7 +603,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
                                 rax,
                                 no_reg,
                                 &undo_allocation,
-                                true);
+                                RESULT_CONTAINS_TOP);
 
     // Initialize the FixedArray.
     // rbx: JSObject
index 8d313c9..31f55ae 100644 (file)
@@ -6576,7 +6576,7 @@ void CompareStub::Generate(MacroAssembler* masm) {
         // One operand is a smi.
 
         // Check whether the non-smi is a heap number.
-        ASSERT_EQ(static_cast<intptr_t>(1), kSmiTagMask);
+        ASSERT_EQ(1, static_cast<int>(kSmiTagMask));
         // rcx still holds rax & kSmiTag, which is either zero or one.
         __ decq(rcx);  // If rax is a smi, all 1s, else all 0s.
         __ movq(rbx, rdx);
@@ -6829,7 +6829,8 @@ void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
 
   // Do the runtime call to allocate the arguments object.
   __ bind(&runtime);
-  __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
+  Runtime::Function* f = Runtime::FunctionForId(Runtime::kNewArgumentsFast);
+  __ TailCallRuntime(ExternalReference(f), 3, f->result_size);
 }
 
 
@@ -6891,7 +6892,9 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
   __ pop(rbx);  // Return address.
   __ push(rdx);
   __ push(rbx);
-  __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
+  Runtime::Function* f =
+      Runtime::FunctionForId(Runtime::kGetArgumentsProperty);
+  __ TailCallRuntime(ExternalReference(f), 1, f->result_size);
 }
 
 
@@ -6915,6 +6918,23 @@ void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
 }
 
 
+int CEntryStub::MinorKey() {
+  ASSERT(result_size_ <= 2);
+#ifdef _WIN64
+  // Simple results returned in rax (using default code).
+  // Complex results must be written to address passed as first argument.
+  // Use even numbers for minor keys, reserving the odd numbers for
+  // CEntryDebugBreakStub.
+  return (result_size_ < 2) ? 0 : result_size_ * 2;
+#else
+  // Single results returned in rax (both AMD64 and Win64 calling conventions)
+  // and a struct of two pointers in rax+rdx (AMD64 calling convention only)
+  // by default.
+  return 0;
+#endif
+}
+
+
 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
   // Check that stack should contain next handler, frame pointer, state and
   // return address in that order.
@@ -6986,8 +7006,18 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
   // Store Arguments object on stack, below the 4 WIN64 ABI parameter slots.
   __ movq(Operand(rsp, 4 * kPointerSize), r14);  // argc.
   __ movq(Operand(rsp, 5 * kPointerSize), r15);  // argv.
-  // Pass a pointer to the Arguments object as the first argument.
-  __ lea(rcx, Operand(rsp, 4 * kPointerSize));
+  if (result_size_ < 2) {
+    // Pass a pointer to the Arguments object as the first argument.
+    // Return result in single register (rax).
+    __ lea(rcx, Operand(rsp, 4 * kPointerSize));
+  } else {
+    ASSERT_EQ(2, result_size_);
+    // Pass a pointer to the result location as the first argument.
+    __ lea(rcx, Operand(rsp, 6 * kPointerSize));
+    // Pass a pointer to the Arguments object as the second argument.
+    __ lea(rdx, Operand(rsp, 4 * kPointerSize));
+  }
+
 #else  // ! defined(_WIN64)
   // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
   __ movq(rdi, r14);  // argc.
@@ -7010,7 +7040,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
   __ j(zero, &failure_returned);
 
   // Exit the JavaScript to C++ exit frame.
-  __ LeaveExitFrame(frame_type);
+  __ LeaveExitFrame(frame_type, result_size_);
   __ ret(0);
 
   // Handling of failure.
@@ -7146,7 +7176,7 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
       StackFrame::EXIT;
 
   // Enter the exit frame that transitions from JavaScript to C++.
-  __ EnterExitFrame(frame_type);
+  __ EnterExitFrame(frame_type, result_size_);
 
   // rax: Holds the context at this point, but should not be used.
   //      On entry to code generated by GenerateCore, it must hold
@@ -7333,7 +7363,8 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
   __ push(rax);
 
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
+  Runtime::Function* f = Runtime::FunctionForId(Runtime::kStackGuard);
+  __ TailCallRuntime(ExternalReference(f), 1, f->result_size);
 }
 
 
@@ -7347,10 +7378,9 @@ void FloatingPointHelper::AllocateHeapNumber(MacroAssembler* masm,
                               scratch,
                               no_reg,
                               need_gc,
-                              false);
+                              TAG_OBJECT);
 
   // Set the map and tag the result.
-  __ addq(result, Immediate(kHeapObjectTag));
   __ LoadRoot(kScratchRegister, Heap::kHeapNumberMapRootIndex);
   __ movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
 }
index f2bb62b..10092c5 100644 (file)
@@ -160,18 +160,6 @@ void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
 }
 
 
-void Debug::GenerateReturnDebugBreakEntry(MacroAssembler* masm) {
-  // OK to clobber rbx as we are returning from a JS function through the code
-  // generated by CodeGenerator::GenerateReturnSequence()
-  ExternalReference debug_break_return =
-      ExternalReference(Debug_Address::DebugBreakReturn());
-  __ movq(rbx, debug_break_return);
-  __ movq(rbx, Operand(rbx, 0));
-  __ addq(rbx, Immediate(Code::kHeaderSize - kHeapObjectTag));
-  __ jmp(rbx);
-}
-
-
 void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
   // REgister state for IC store call (from ic-x64.cc).
   // ----------- S t a t e -------------
@@ -207,7 +195,7 @@ bool BreakLocationIterator::IsDebugBreakAtReturn()  {
 
 void BreakLocationIterator::SetDebugBreakAtReturn()  {
   ASSERT(Debug::kX64JSReturnSequenceLength >= Debug::kX64CallInstructionLength);
-  rinfo()->PatchCodeWithCall(Debug::debug_break_return_entry()->entry(),
+  rinfo()->PatchCodeWithCall(Debug::debug_break_return()->entry(),
       Debug::kX64JSReturnSequenceLength - Debug::kX64CallInstructionLength);
 }
 
index e2f7c30..bf415d9 100644 (file)
@@ -236,7 +236,7 @@ void KeyedLoadIC::Generate(MacroAssembler* masm,
   __ push(rbx);  // return address
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 2);
+  __ TailCallRuntime(f, 2, 1);
 }
 
 
@@ -373,7 +373,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
   __ push(rcx);  // return address
 
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(f, 3);
+  __ TailCallRuntime(f, 3, 1);
 }
 
 
@@ -394,7 +394,7 @@ void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
 
   // Do tail-call to runtime routine.
   __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
+      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
 }
 
 
@@ -460,7 +460,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
   __ push(rax);
   __ push(rcx);
   // Do tail-call to runtime routine.
-  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
+  __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
 
 
   // Extra capacity case: Check if there is extra capacity to
@@ -532,7 +532,7 @@ void CallIC::Generate(MacroAssembler* masm,
   __ push(rbx);
 
   // Call the entry.
-  CEntryStub stub;
+  CEntryStub stub(1);
   __ movq(rax, Immediate(2));
   __ movq(rbx, f);
   __ CallStub(&stub);
@@ -763,7 +763,7 @@ void LoadIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
   __ push(rbx);  // return address
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 2);
+  __ TailCallRuntime(f, 2, 1);
 }
 
 
@@ -940,7 +940,7 @@ void StoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
   __ push(rbx);  // return address
 
   // Perform tail call to the entry.
-  __ TailCallRuntime(f, 3);
+  __ TailCallRuntime(f, 3, 1);
 }
 
 void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
@@ -959,7 +959,7 @@ void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
 
   // Perform tail call to the entry.
   __ TailCallRuntime(
-      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
+      ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
 }
 
 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
index ae45eab..104ccb8 100644 (file)
@@ -318,7 +318,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
 
 
 void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
-                                     int num_arguments) {
+                                     int num_arguments,
+                                     int result_size) {
   // ----------- S t a t e -------------
   //  -- rsp[0] : return address
   //  -- rsp[8] : argument num_arguments - 1
@@ -331,14 +332,15 @@ void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
   // should remove this need and make the runtime routine entry code
   // smarter.
   movq(rax, Immediate(num_arguments));
-  JumpToBuiltin(ext);
+  JumpToBuiltin(ext, result_size);
 }
 
 
-void MacroAssembler::JumpToBuiltin(const ExternalReference& ext) {
+void MacroAssembler::JumpToBuiltin(const ExternalReference& ext,
+                                   int result_size) {
   // Set the entry point and jump to the C entry runtime stub.
   movq(rbx, ext);
-  CEntryStub ces;
+  CEntryStub ces(result_size);
   movq(kScratchRegister, ces.GetCode(), RelocInfo::CODE_TARGET);
   jmp(kScratchRegister);
 }
@@ -971,7 +973,7 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
 
 
 
-void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
+void MacroAssembler::EnterExitFrame(StackFrame::Type type, int result_size) {
   ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG);
 
   // Setup the frame structure on the stack.
@@ -1016,6 +1018,21 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
   }
 #endif
 
+#ifdef _WIN64
+  // Reserve space on stack for result and argument structures, if necessary.
+  int result_stack_space = (result_size < 2) ? 0 : result_size * kPointerSize;
+  // Reserve space for the Arguments object.  The Windows 64-bit ABI
+  // requires us to pass this structure as a pointer to its location on
+  // the stack.  The structure contains 2 values.
+  int argument_stack_space = 2 * kPointerSize;
+  // We also need backing space for 4 parameters, even though
+  // we only pass one or two parameter, and it is in a register.
+  int argument_mirror_space = 4 * kPointerSize;
+  int total_stack_space =
+      argument_mirror_space + argument_stack_space + result_stack_space;
+  subq(rsp, Immediate(total_stack_space));
+#endif
+
   // Get the required frame alignment for the OS.
   static const int kFrameAlignment = OS::ActivationFrameAlignment();
   if (kFrameAlignment > 0) {
@@ -1024,30 +1041,19 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
     and_(rsp, kScratchRegister);
   }
 
-#ifdef _WIN64
-  // Reserve space for the Arguments object.  The Windows 64-bit ABI
-  // requires us to pass this structure as a pointer to its location on
-  // the stack.  The structure contains 2 pointers.
-  // The structure on the stack must be 16-byte aligned.
-  // We also need backing space for 4 parameters, even though
-  // we only pass one parameter, and it is in a register.
-  subq(rsp, Immediate(6 * kPointerSize));
-  ASSERT(kFrameAlignment == 2 * kPointerSize);  // Change the padding if needed.
-#endif
-
   // Patch the saved entry sp.
   movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
 }
 
 
-void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
+void MacroAssembler::LeaveExitFrame(StackFrame::Type type, int result_size) {
   // Registers:
   // r15 : argv
 #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) {
-    // It's okay to clobber register ebx below because we don't need
+    // It's okay to clobber register rbx below because we don't need
     // the function pointer after this.
     const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize;
     int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize;
@@ -1060,7 +1066,18 @@ void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
   movq(rcx, Operand(rbp, 1 * kPointerSize));
   movq(rbp, Operand(rbp, 0 * kPointerSize));
 
-  // Pop the arguments and the receiver from the caller stack.
+#ifdef _WIN64
+  // If return value is on the stack, pop it to registers.
+  if (result_size > 1) {
+    ASSERT_EQ(2, result_size);
+    // Position above 4 argument mirrors and arguments object.
+    movq(rax, Operand(rsp, 6 * kPointerSize));
+    movq(rdx, Operand(rsp, 7 * kPointerSize));
+  }
+#endif
+
+  // Pop everything up to and including the arguments and the receiver
+  // from the caller stack.
   lea(rsp, Operand(r15, 1 * kPointerSize));
 
   // Restore current context from top and clear it in debug mode.
@@ -1231,18 +1248,23 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
 }
 
 
-void MacroAssembler::LoadAllocationTopHelper(
-    Register result,
-    Register result_end,
-    Register scratch,
-    bool result_contains_top_on_entry) {
+void MacroAssembler::LoadAllocationTopHelper(Register result,
+                                             Register result_end,
+                                             Register scratch,
+                                             AllocationFlags flags) {
   ExternalReference new_space_allocation_top =
       ExternalReference::new_space_allocation_top_address();
 
   // Just return if allocation top is already known.
-  if (result_contains_top_on_entry) {
+  if ((flags & RESULT_CONTAINS_TOP) != 0) {
     // No use of scratch if allocation top is provided.
     ASSERT(scratch.is(no_reg));
+#ifdef DEBUG
+    // Assert that result actually contains top on entry.
+    movq(kScratchRegister, new_space_allocation_top);
+    cmpq(result, Operand(kScratchRegister, 0));
+    Check(equal, "Unexpected allocation top");
+#endif
     return;
   }
 
@@ -1279,20 +1301,16 @@ void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
 }
 
 
-void MacroAssembler::AllocateObjectInNewSpace(
-    int object_size,
-    Register result,
-    Register result_end,
-    Register scratch,
-    Label* gc_required,
-    bool result_contains_top_on_entry) {
+void MacroAssembler::AllocateObjectInNewSpace(int object_size,
+                                              Register result,
+                                              Register result_end,
+                                              Register scratch,
+                                              Label* gc_required,
+                                              AllocationFlags flags) {
   ASSERT(!result.is(result_end));
 
   // Load address of new object into result.
-  LoadAllocationTopHelper(result,
-                          result_end,
-                          scratch,
-                          result_contains_top_on_entry);
+  LoadAllocationTopHelper(result, result_end, scratch, flags);
 
   // Calculate new top and bail out if new space is exhausted.
   ExternalReference new_space_allocation_limit =
@@ -1304,25 +1322,26 @@ void MacroAssembler::AllocateObjectInNewSpace(
 
   // Update allocation top.
   UpdateAllocationTopHelper(result_end, scratch);
+
+  // Tag the result if requested.
+  if ((flags & TAG_OBJECT) != 0) {
+    addq(result, Immediate(kHeapObjectTag));
+  }
 }
 
 
-void MacroAssembler::AllocateObjectInNewSpace(
-    int header_size,
-    ScaleFactor element_size,
-    Register element_count,
-    Register result,
-    Register result_end,
-    Register scratch,
-    Label* gc_required,
-    bool result_contains_top_on_entry) {
+void MacroAssembler::AllocateObjectInNewSpace(int header_size,
+                                              ScaleFactor element_size,
+                                              Register element_count,
+                                              Register result,
+                                              Register result_end,
+                                              Register scratch,
+                                              Label* gc_required,
+                                              AllocationFlags flags) {
   ASSERT(!result.is(result_end));
 
   // Load address of new object into result.
-  LoadAllocationTopHelper(result,
-                          result_end,
-                          scratch,
-                          result_contains_top_on_entry);
+  LoadAllocationTopHelper(result, result_end, scratch, flags);
 
   // Calculate new top and bail out if new space is exhausted.
   ExternalReference new_space_allocation_limit =
@@ -1334,23 +1353,22 @@ void MacroAssembler::AllocateObjectInNewSpace(
 
   // Update allocation top.
   UpdateAllocationTopHelper(result_end, scratch);
-}
 
+  // Tag the result if requested.
+  if ((flags & TAG_OBJECT) != 0) {
+    addq(result, Immediate(kHeapObjectTag));
+  }
+}
 
-void MacroAssembler::AllocateObjectInNewSpace(
-    Register object_size,
-    Register result,
-    Register result_end,
-    Register scratch,
-    Label* gc_required,
-    bool result_contains_top_on_entry) {
 
+void MacroAssembler::AllocateObjectInNewSpace(Register object_size,
+                                              Register result,
+                                              Register result_end,
+                                              Register scratch,
+                                              Label* gc_required,
+                                              AllocationFlags flags) {
   // Load address of new object into result.
-  LoadAllocationTopHelper(result,
-                          result_end,
-                          scratch,
-                          result_contains_top_on_entry);
-
+  LoadAllocationTopHelper(result, result_end, scratch, flags);
 
   // Calculate new top and bail out if new space is exhausted.
   ExternalReference new_space_allocation_limit =
@@ -1365,6 +1383,11 @@ void MacroAssembler::AllocateObjectInNewSpace(
 
   // Update allocation top.
   UpdateAllocationTopHelper(result_end, scratch);
+
+  // Tag the result if requested.
+  if ((flags & TAG_OBJECT) != 0) {
+    addq(result, Immediate(kHeapObjectTag));
+  }
 }
 
 
index 6f5c32c..9da2676 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2009 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -42,25 +42,6 @@ static const Register kScratchRegister = r10;
 class JumpTarget;
 
 
-// Helper types to make flags easier to read at call sites.
-enum InvokeFlag {
-  CALL_FUNCTION,
-  JUMP_FUNCTION
-};
-
-enum CodeLocation {
-  IN_JAVASCRIPT,
-  IN_JS_ENTRY,
-  IN_C_ENTRY
-};
-
-enum HandlerType {
-  TRY_CATCH_HANDLER,
-  TRY_FINALLY_HANDLER,
-  JS_ENTRY_HANDLER
-};
-
-
 // MacroAssembler implements a collection of frequently used macros.
 class MacroAssembler: public Assembler {
  public:
@@ -106,15 +87,15 @@ class MacroAssembler: public Assembler {
   void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
 
   // Enter specific kind of exit frame; either EXIT or
-  // EXIT_DEBUG. Expects the number of arguments in register eax and
-  // sets up the number of arguments in register edi and the pointer
-  // to the first argument in register esi.
-  void EnterExitFrame(StackFrame::Type type);
+  // EXIT_DEBUG. Expects the number of arguments in register rax and
+  // sets up the number of arguments in register rdi and the pointer
+  // to the first argument in register rsi.
+  void EnterExitFrame(StackFrame::Type type, int result_size = 1);
 
-  // Leave the current exit frame. Expects the return value in
-  // register eax:edx (untouched) and the pointer to the first
-  // argument in register esi.
-  void LeaveExitFrame(StackFrame::Type type);
+  // Leave the current exit frame. Expects/provides the return value in
+  // register rax:rdx (untouched) and the pointer to the first
+  // argument in register rsi.
+  void LeaveExitFrame(StackFrame::Type type, int result_size = 1);
 
 
   // ---------------------------------------------------------------------------
@@ -244,7 +225,7 @@ class MacroAssembler: public Assembler {
                                 Register result_end,
                                 Register scratch,
                                 Label* gc_required,
-                                bool result_contains_top_on_entry);
+                                AllocationFlags flags);
 
   void AllocateObjectInNewSpace(int header_size,
                                 ScaleFactor element_size,
@@ -253,14 +234,14 @@ class MacroAssembler: public Assembler {
                                 Register result_end,
                                 Register scratch,
                                 Label* gc_required,
-                                bool result_contains_top_on_entry);
+                                AllocationFlags flags);
 
   void AllocateObjectInNewSpace(Register object_size,
                                 Register result,
                                 Register result_end,
                                 Register scratch,
                                 Label* gc_required,
-                                bool result_contains_top_on_entry);
+                                AllocationFlags flags);
 
   // Undo allocation in new space. The object passed and objects allocated after
   // it will no longer be allocated. Make sure that no pointers are left to the
@@ -317,10 +298,12 @@ class MacroAssembler: public Assembler {
   // Tail call of a runtime routine (jump).
   // Like JumpToBuiltin, but also takes care of passing the number
   // of arguments.
-  void TailCallRuntime(const ExternalReference& ext, int num_arguments);
+  void TailCallRuntime(const ExternalReference& ext,
+                       int num_arguments,
+                       int result_size);
 
   // Jump to the builtin routine.
-  void JumpToBuiltin(const ExternalReference& ext);
+  void JumpToBuiltin(const ExternalReference& ext, int result_size);
 
 
   // ---------------------------------------------------------------------------
@@ -392,31 +375,11 @@ class MacroAssembler: public Assembler {
   void LoadAllocationTopHelper(Register result,
                                Register result_end,
                                Register scratch,
-                               bool result_contains_top_on_entry);
+                               AllocationFlags flags);
   void UpdateAllocationTopHelper(Register result_end, Register scratch);
 };
 
 
-// The code patcher is used to patch (typically) small parts of code e.g. for
-// debugging and other types of instrumentation. When using the code patcher
-// the exact number of bytes specified must be emitted. Is not legal to emit
-// relocation information. If any of these constraints are violated it causes
-// an assertion.
-class CodePatcher {
- public:
-  CodePatcher(byte* address, int size);
-  virtual ~CodePatcher();
-
-  // Macro assembler to emit code.
-  MacroAssembler* masm() { return &masm_; }
-
- private:
-  byte* address_;  // The address of the code being patched.
-  int size_;  // Number of bytes of the expected patch size.
-  MacroAssembler masm_;  // Macro assembler used to generate the code.
-};
-
-
 // -----------------------------------------------------------------------------
 // Static helper functions.
 
index 373f359..5d17a2d 100644 (file)
@@ -612,7 +612,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
   // MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots.
   // Store register parameters in pre-allocated stack slots,
   __ movq(Operand(rbp, kInputString), rcx);
-  __ movq(Operand(rbp, kStartIndex), rdx);
+  __ movq(Operand(rbp, kStartIndex), rdx);  // Passed as int32 in edx.
   __ movq(Operand(rbp, kInputStart), r8);
   __ movq(Operand(rbp, kInputEnd), r9);
   // Callee-save on Win64.
@@ -711,7 +711,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
   __ Move(code_object_pointer(), masm_->CodeObject());
   // Load previous char as initial value of current-character.
   Label at_start;
-  __ cmpq(Operand(rbp, kAtStart), Immediate(0));
+  __ cmpb(Operand(rbp, kAtStart), Immediate(0));
   __ j(not_equal, &at_start);
   LoadCurrentCharacterUnchecked(-1, 1);  // Load previous char.
   __ jmp(&start_label_);
index ab96477..3e6720d 100644 (file)
@@ -129,16 +129,18 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
   static const int kReturn_eip = kFramePointer + kPointerSize;
   static const int kFrameAlign = kReturn_eip + kPointerSize;
 
-#ifdef __MSVC__
+#ifdef _WIN64
   // Parameters (first four passed as registers, but with room on stack).
   // In Microsoft 64-bit Calling Convention, there is room on the callers
   // stack (before the return address) to spill parameter registers. We
   // use this space to store the register passed parameters.
   static const int kInputString = kFrameAlign;
+  // StartIndex is passed as 32 bit int.
   static const int kStartIndex = kInputString + kPointerSize;
   static const int kInputStart = kStartIndex + kPointerSize;
   static const int kInputEnd = kInputStart + kPointerSize;
   static const int kRegisterOutput = kInputEnd + kPointerSize;
+  // AtStart is passed as 32 bit int (values 0 or 1).
   static const int kAtStart = kRegisterOutput + kPointerSize;
   static const int kStackHighEnd = kAtStart + kPointerSize;
 #else
@@ -154,7 +156,7 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
   static const int kStackHighEnd = kFrameAlign;
 #endif
 
-#ifdef __MSVC__
+#ifdef _WIN64
   // Microsoft calling convention has three callee-saved registers
   // (that we are using). We push these after the frame pointer.
   static const int kBackup_rsi = kFramePointer - kPointerSize;
index fcddfc4..fcb2092 100644 (file)
@@ -354,7 +354,7 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
   __ movq(rax, Immediate(5));
   __ movq(rbx, ref);
 
-  CEntryStub stub;
+  CEntryStub stub(1);
   __ CallStub(&stub);
 }
 
@@ -489,7 +489,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
 
       ExternalReference ref =
           ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
-      __ TailCallRuntime(ref, 5);
+      __ TailCallRuntime(ref, 5, 1);
 
       __ bind(&cleanup);
       __ pop(scratch1);
@@ -511,7 +511,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
 
     ExternalReference ref = ExternalReference(
         IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
-    __ TailCallRuntime(ref, 5);
+    __ TailCallRuntime(ref, 5, 1);
   }
 
  private:
@@ -661,7 +661,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
     __ movq(rax, Immediate(5));
     __ movq(rbx, ref);
 
-    CEntryStub stub;
+    CEntryStub stub(1);
     __ CallStub(&stub);
 
     __ LeaveInternalFrame();
@@ -1362,7 +1362,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
   // Do tail-call to the runtime system.
   ExternalReference store_callback_property =
       ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
-  __ TailCallRuntime(store_callback_property, 4);
+  __ TailCallRuntime(store_callback_property, 4, 1);
 
   // Handle store cache miss.
   __ bind(&miss);
@@ -1450,7 +1450,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
   // Do tail-call to the runtime system.
   ExternalReference store_ic_property =
       ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
-  __ TailCallRuntime(store_ic_property, 3);
+  __ TailCallRuntime(store_ic_property, 3, 1);
 
   // Handle store cache miss.
   __ bind(&miss);
@@ -1652,7 +1652,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
   // Do tail-call to the runtime system.
   ExternalReference load_callback_property =
       ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
-  __ TailCallRuntime(load_callback_property, 5);
+  __ TailCallRuntime(load_callback_property, 5, 1);
 }
 
 
@@ -1784,10 +1784,12 @@ Object* ConstructStubCompiler::CompileConstructStub(
   // rbx: initial map
   __ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset));
   __ shl(rcx, Immediate(kPointerSizeLog2));
-  // Make sure that the maximum heap object size will never cause us
-  // problems here.
-  ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize);
-  __ AllocateObjectInNewSpace(rcx, rdx, rcx, no_reg, &generic_stub_call, false);
+  __ AllocateObjectInNewSpace(rcx,
+                              rdx,
+                              rcx,
+                              no_reg,
+                              &generic_stub_call,
+                              NO_ALLOCATION_FLAGS);
 
   // Allocated the JSObject, now initialize the fields and add the heap tag.
   // rbx: initial map
index 67e9d8a..68aabb5 100644 (file)
@@ -50,10 +50,6 @@ test-api/RegExpInterruption: SKIP
 test-api/OutOfMemory: SKIP
 test-api/OutOfMemoryNested: SKIP
 
-# BUG(432): Fail on ARM hardware.
-test-regexp/MacroAssemblerNativeSimple: PASS || FAIL
-test-regexp/MacroAssemblerNativeSimpleUC16: PASS || FAIL
-
 # BUG(355): Test crashes on ARM.
 test-log/ProfLazyMode: SKIP
 
index 34f1639..f6e4d04 100644 (file)
@@ -37,9 +37,9 @@ using namespace v8::internal;
 
 
 // Define these function prototypes to match JSEntryFunction in execution.cc.
-typedef int (*F1)(int x, int p1, int p2, int p3, int p4);
-typedef int (*F2)(int x, int y, int p2, int p3, int p4);
-typedef int (*F3)(void* p, int p1, int p2, int p3, int p4);
+typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
+typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
+typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
 
 
 static v8::Persistent<v8::Context> env;
index bd09d0d..0cae26c 100644 (file)
@@ -4503,14 +4503,16 @@ TEST(DebuggerHostDispatch) {
 
 
 TEST(DebuggerAgent) {
-  // Make sure this port is not used by other tests to allow tests to run in
+  // Make sure these ports is not used by other tests to allow tests to run in
   // parallel.
-  const int kPort = 5858;
+  const int kPort1 = 5858;
+  const int kPort2 = 5857;
+  const int kPort3 = 5856;
 
-  // Make a string with the port number.
+  // Make a string with the port2 number.
   const int kPortBufferLen = 6;
-  char port_str[kPortBufferLen];
-  OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort);
+  char port2_str[kPortBufferLen];
+  OS::SNPrintF(i::Vector<char>(port2_str, kPortBufferLen), "%d", kPort2);
 
   bool ok;
 
@@ -4518,15 +4520,15 @@ TEST(DebuggerAgent) {
   i::Socket::Setup();
 
   // Test starting and stopping the agent without any client connection.
-  i::Debugger::StartAgent("test", kPort);
+  i::Debugger::StartAgent("test", kPort1);
   i::Debugger::StopAgent();
 
   // Test starting the agent, connecting a client and shutting down the agent
   // with the client connected.
-  ok = i::Debugger::StartAgent("test", kPort);
+  ok = i::Debugger::StartAgent("test", kPort2);
   CHECK(ok);
   i::Socket* client = i::OS::CreateSocket();
-  ok = client->Connect("localhost", port_str);
+  ok = client->Connect("localhost", port2_str);
   CHECK(ok);
   i::Debugger::StopAgent();
   delete client;
@@ -4534,9 +4536,9 @@ TEST(DebuggerAgent) {
   // Test starting and stopping the agent with the required port already
   // occoupied.
   i::Socket* server = i::OS::CreateSocket();
-  server->Bind(kPort);
+  server->Bind(kPort3);
 
-  i::Debugger::StartAgent("test", kPort);
+  i::Debugger::StartAgent("test", kPort3);
   i::Debugger::StopAgent();
 
   delete server;
index 5884a41..dafd3aa 100644 (file)
@@ -5,12 +5,15 @@
 #ifdef ENABLE_LOGGING_AND_PROFILING
 
 #ifdef __linux__
+#include <math.h>
+#include <pthread.h>
 #include <signal.h>
 #include <unistd.h>
-#endif
+#endif  // __linux__
 
 #include "v8.h"
 #include "log.h"
+#include "v8threads.h"
 #include "cctest.h"
 
 using v8::internal::Address;
@@ -155,9 +158,10 @@ static bool was_sigprof_received = true;
 #ifdef __linux__
 
 struct sigaction old_sigprof_handler;
+pthread_t our_thread;
 
 static void SigProfSignalHandler(int signal, siginfo_t* info, void* context) {
-  if (signal != SIGPROF) return;
+  if (signal != SIGPROF || !pthread_equal(pthread_self(), our_thread)) return;
   was_sigprof_received = true;
   old_sigprof_handler.sa_sigaction(signal, info, context);
 }
@@ -185,6 +189,7 @@ static int CheckThatProfilerWorks(int log_pos) {
   // Intercept SIGPROF handler to make sure that the test process
   // had received it. Under load, system can defer it causing test failure.
   // It is important to execute this after 'ResumeProfiler'.
+  our_thread = pthread_self();
   was_sigprof_received = false;
   struct sigaction sa;
   sa.sa_sigaction = SigProfSignalHandler;
@@ -280,6 +285,158 @@ TEST(ProfLazyMode) {
 }
 
 
+// Profiling multiple threads that use V8 is currently only available on Linux.
+#ifdef __linux__
+
+namespace {
+
+class LoopingThread : public v8::internal::Thread {
+ public:
+  LoopingThread()
+      : v8::internal::Thread(),
+        semaphore_(v8::internal::OS::CreateSemaphore(0)),
+        run_(true) {
+  }
+
+  virtual ~LoopingThread() { delete semaphore_; }
+
+  void Run() {
+    self_ = pthread_self();
+    RunLoop();
+  }
+
+  void SendSigProf() { pthread_kill(self_, SIGPROF); }
+
+  void Stop() { run_ = false; }
+
+  bool WaitForRunning() { return semaphore_->Wait(1000000); }
+
+ protected:
+  bool IsRunning() { return run_; }
+
+  virtual void RunLoop() = 0;
+
+  void SetV8ThreadId() {
+    v8_thread_id_ = v8::V8::GetCurrentThreadId();
+  }
+
+  void SignalRunning() { semaphore_->Signal(); }
+
+ private:
+  v8::internal::Semaphore* semaphore_;
+  bool run_;
+  pthread_t self_;
+  int v8_thread_id_;
+};
+
+
+class LoopingJsThread : public LoopingThread {
+ public:
+  void RunLoop() {
+    {
+      v8::Locker locker;
+      CHECK(v8::internal::ThreadManager::HasId());
+      SetV8ThreadId();
+    }
+    while (IsRunning()) {
+      v8::Locker locker;
+      v8::HandleScope scope;
+      v8::Persistent<v8::Context> context = v8::Context::New();
+      v8::Context::Scope context_scope(context);
+      SignalRunning();
+      CompileAndRunScript(
+          "var j; for (var i=0; i<10000; ++i) { j = Math.sin(i); }");
+      context.Dispose();
+      i::OS::Sleep(1);
+    }
+  }
+};
+
+
+class LoopingNonJsThread : public LoopingThread {
+ public:
+  void RunLoop() {
+    v8::Locker locker;
+    v8::Unlocker unlocker;
+    // Now thread has V8's id, but will not run VM code.
+    CHECK(v8::internal::ThreadManager::HasId());
+    double i = 10;
+    SignalRunning();
+    while (IsRunning()) {
+      i = sin(i);
+      i::OS::Sleep(1);
+    }
+  }
+};
+
+
+class TestSampler : public v8::internal::Sampler {
+ public:
+  TestSampler()
+      : Sampler(0, true),
+        semaphore_(v8::internal::OS::CreateSemaphore(0)),
+        was_sample_stack_called_(false) {
+  }
+
+  ~TestSampler() { delete semaphore_; }
+
+  void SampleStack(v8::internal::TickSample*) {
+    was_sample_stack_called_ = true;
+  }
+
+  void Tick(v8::internal::TickSample*) { semaphore_->Signal(); }
+
+  bool WaitForTick() { return semaphore_->Wait(1000000); }
+
+  void Reset() { was_sample_stack_called_ = false; }
+
+  bool WasSampleStackCalled() { return was_sample_stack_called_; }
+
+ private:
+  v8::internal::Semaphore* semaphore_;
+  bool was_sample_stack_called_;
+};
+
+
+}  // namespace
+
+TEST(ProfMultipleThreads) {
+  // V8 needs to be initialized before the first Locker
+  // instantiation. Otherwise, Top::Initialize will reset
+  // thread_id_ in ThreadTopLocal.
+  v8::HandleScope scope;
+  v8::Handle<v8::Context> env = v8::Context::New();
+  env->Enter();
+
+  LoopingJsThread jsThread;
+  jsThread.Start();
+  LoopingNonJsThread nonJsThread;
+  nonJsThread.Start();
+
+  TestSampler sampler;
+  sampler.Start();
+  CHECK(!sampler.WasSampleStackCalled());
+  jsThread.WaitForRunning();
+  jsThread.SendSigProf();
+  CHECK(sampler.WaitForTick());
+  CHECK(sampler.WasSampleStackCalled());
+  sampler.Reset();
+  CHECK(!sampler.WasSampleStackCalled());
+  nonJsThread.WaitForRunning();
+  nonJsThread.SendSigProf();
+  CHECK(sampler.WaitForTick());
+  CHECK(!sampler.WasSampleStackCalled());
+  sampler.Stop();
+
+  jsThread.Stop();
+  nonJsThread.Stop();
+  jsThread.Join();
+  nonJsThread.Join();
+}
+
+#endif  // __linux__
+
+
 static inline bool IsStringEqualTo(const char* r, const char* s) {
   return strncmp(r, s, strlen(r)) == 0;
 }
index 75377db..c2427c8 100644 (file)
@@ -31,7 +31,7 @@ from os.path import join, dirname, exists
 import platform
 import utils
 
-DEBUG_FLAGS = ['--enable-slow-asserts', '--debug-code', '--verify-heap']
+CCTEST_DEBUG_FLAGS = ['--enable-slow-asserts', '--debug-code', '--verify-heap']
 
 
 class CcTestCase(test.TestCase):
@@ -55,7 +55,7 @@ class CcTestCase(test.TestCase):
     serialization_option = '--testing_serialization_file=' + serialization_file
     result = [ self.executable, name, serialization_option ]
     if self.mode == 'debug':
-      result += DEBUG_FLAGS
+      result += CCTEST_DEBUG_FLAGS
     return result
 
   def GetCommand(self):
index 7b477e1..e87cbb7 100644 (file)
@@ -140,6 +140,11 @@ function CheckScopeContent(content, number, exec_state) {
   if (!scope.scopeObject().property('arguments').isUndefined()) {
     scope_size--;
   }
+  // Also ignore synthetic variable from catch block.
+  if (!scope.scopeObject().property('.catch-var').isUndefined()) {
+    scope_size--;
+  }
+
   if (count != scope_size) {
     print('Names found in scope:');
     var names = scope.scopeObject().propertyNames();
@@ -656,5 +661,101 @@ listener_delegate = function(exec_state) {
 debugger;
 EndTest();
 
+
+BeginTest("Catch block 1");
+function catch_block_1() {
+  try {
+    throw 'Exception';
+  } catch (e) {
+    debugger;
+  }
+};
+
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Catch,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({e:'Exception'}, 0, exec_state);
+}
+catch_block_1()
+EndTest();
+
+
+BeginTest("Catch block 2");
+function catch_block_2() {
+  try {
+    throw 'Exception';
+  } catch (e) {
+    with({n:10}) {
+      debugger;
+    }
+  }
+};
+
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.With,
+                   debug.ScopeType.Catch,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({n:10}, 0, exec_state);
+  CheckScopeContent({e:'Exception'}, 1, exec_state);
+}
+catch_block_2()
+EndTest();
+
+
+BeginTest("Catch block 3");
+function catch_block_1() {
+  // Do eval to dynamically declare a local variable so that the context's
+  // extension slot is initialized with JSContextExtensionObject.
+  eval("var y = 78;");
+  try {
+    throw 'Exception';
+  } catch (e) {
+    debugger;
+  }
+};
+
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Catch,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({e:'Exception'}, 0, exec_state);
+  CheckScopeContent({y:78}, 1, exec_state);
+}
+catch_block_1()
+EndTest();
+
+
+BeginTest("Catch block 4");
+function catch_block_2() {
+  // Do eval to dynamically declare a local variable so that the context's
+  // extension slot is initialized with JSContextExtensionObject.
+  eval("var y = 98;");
+  try {
+    throw 'Exception';
+  } catch (e) {
+    with({n:10}) {
+      debugger;
+    }
+  }
+};
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.With,
+                   debug.ScopeType.Catch,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({n:10}, 0, exec_state);
+  CheckScopeContent({e:'Exception'}, 1, exec_state);
+  CheckScopeContent({y:98}, 2, exec_state);
+}
+catch_block_2()
+EndTest();
+
+
 assertEquals(begin_test_count, break_count, 'one or more tests did not enter the debugger');
 assertEquals(begin_test_count, end_test_count, 'one or more tests did not have its result checked');
index fbb8078..50d095b 100644 (file)
@@ -54,7 +54,7 @@ function f() {
 
 break_break_point_hit_count = 0;
 f();
-assertEquals(5, break_break_point_hit_count);
+assertEquals(6, break_break_point_hit_count);
 
 // Use an inner function to ensure that the function call is through CodeStub
 // CallFunction see Ia32CodeGenerator::VisitCall and
@@ -67,7 +67,21 @@ function g() {
 
 break_break_point_hit_count = 0;
 g();
-assertEquals(4, break_break_point_hit_count);
+assertEquals(5, break_break_point_hit_count);
+
+
+// Use an inner function to ensure that the function call is through CodeStub
+// CallFunction.
+function testCallInExpreesion() {
+  function h() {}
+  debugger;
+  var x = 's' + h(10, 20);
+};
+
+break_break_point_hit_count = 0;
+testCallInExpreesion();
+assertEquals(5, break_break_point_hit_count);
+
 
 // Get rid of the debug event listener.
 Debug.setListener(null);
diff --git a/deps/v8/test/mjsunit/debug-stepin-call-function-stub.js b/deps/v8/test/mjsunit/debug-stepin-call-function-stub.js
new file mode 100644 (file)
index 0000000..12f5142
--- /dev/null
@@ -0,0 +1,115 @@
+// Copyright 2009 the V8 project authors. All rights reserved.\r
+// Redistribution and use in source and binary forms, with or without\r
+// modification, are permitted provided that the following conditions are\r
+// met:\r
+//\r
+//     * Redistributions of source code must retain the above copyright\r
+//       notice, this list of conditions and the following disclaimer.\r
+//     * Redistributions in binary form must reproduce the above\r
+//       copyright notice, this list of conditions and the following\r
+//       disclaimer in the documentation and/or other materials provided\r
+//       with the distribution.\r
+//     * Neither the name of Google Inc. nor the names of its\r
+//       contributors may be used to endorse or promote products derived\r
+//       from this software without specific prior written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+// Flags: --expose-debug-as debug\r
+// Get the Debug object exposed from the debug context global object.\r
+Debug = debug.Debug\r
+\r
+var exception = null;\r
+var state = 0;\r
+var expected_function_name = null;\r
+var expected_source_line_text = null;\r
+var expected_caller_source_line = null;\r
+var step_in_count = 2;\r
+\r
+// Simple debug event handler which first time will cause 'step in' action\r
+// to get into g.call and than check that execution is pauesed inside\r
+// function 'g'.\r
+function listener(event, exec_state, event_data, data) {\r
+  try {\r
+    if (event == Debug.DebugEvent.Break) {\r
+      if (state == 0) {\r
+        // Step into f().\r
+        exec_state.prepareStep(Debug.StepAction.StepIn, step_in_count);\r
+        state = 2;\r
+      } else if (state == 2) {\r
+        assertEquals(expected_source_line_text,\r
+                     event_data.sourceLineText());\r
+        assertEquals(expected_function_name, event_data.func().name());\r
+        state = 3;\r
+      }\r
+    }\r
+  } catch(e) {\r
+    exception = e;\r
+  }\r
+};\r
+\r
+// Add the debug event listener.\r
+Debug.setListener(listener);\r
+\r
+\r
+function g() { \r
+   return "s";  // expected line\r
+}\r
+\r
+function testFunction() {\r
+  var f = g;\r
+  var s = 1 +f(10);\r
+}\r
+\r
+function g2() { \r
+   return "s2";  // expected line\r
+}\r
+\r
+function testFunction2() {\r
+  var f = g2;\r
+  var s = 1 +f(10, 20);\r
+}\r
+\r
+// Run three times. First time the function will be compiled lazily,\r
+// second time cached version will be used.\r
+for (var i = 0; i < 3; i++) {\r
+  state = 0;\r
+  expected_function_name = 'g';\r
+  expected_source_line_text = '   return "s";  // expected line';\r
+  step_in_count = 2;\r
+  // Set a break point and call to invoke the debug event listener.\r
+  Debug.setBreakPoint(testFunction, 1, 0);\r
+  testFunction();\r
+  assertNull(exception);\r
+  assertEquals(3, state);\r
+}\r
+\r
+// Test stepping into function call when a breakpoint is set at the place\r
+// of call. Use different pair of functions so that g2 is compiled lazily.\r
+// Run twice: first time function will be compiled lazily, second time\r
+// cached version will be used.\r
+for (var i = 0; i < 3; i++) {\r
+  state = 0;\r
+  expected_function_name = 'g2';\r
+  expected_source_line_text = '   return "s2";  // expected line';\r
+  step_in_count = 1;\r
+  // Set a break point and call to invoke the debug event listener.\r
+  Debug.setBreakPoint(testFunction2, 2, 0);\r
+  testFunction2();\r
+  assertNull(exception);\r
+  assertEquals(3, state);\r
+}\r
+\r
+\r
+// Get rid of the debug event listener.\r
+Debug.setListener(null);\r
diff --git a/deps/v8/test/mjsunit/debug-stepout-recursive-function.js b/deps/v8/test/mjsunit/debug-stepout-recursive-function.js
new file mode 100644 (file)
index 0000000..2f8780c
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright 2009 the V8 project authors. All rights reserved.\r
+// Redistribution and use in source and binary forms, with or without\r
+// modification, are permitted provided that the following conditions are\r
+// met:\r
+//\r
+//     * Redistributions of source code must retain the above copyright\r
+//       notice, this list of conditions and the following disclaimer.\r
+//     * Redistributions in binary form must reproduce the above\r
+//       copyright notice, this list of conditions and the following\r
+//       disclaimer in the documentation and/or other materials provided\r
+//       with the distribution.\r
+//     * Neither the name of Google Inc. nor the names of its\r
+//       contributors may be used to endorse or promote products derived\r
+//       from this software without specific prior written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+// Flags: --expose-debug-as debug\r
+// Get the Debug object exposed from the debug context global object.\r
+Debug = debug.Debug\r
+\r
+var exception = null;\r
+var step_out_count = 1;\r
+\r
+// Simple debug event handler which counts the number of breaks hit and steps.\r
+var break_point_hit_count = 0;\r
+function listener(event, exec_state, event_data, data) {\r
+  try {\r
+    if (event == Debug.DebugEvent.Break) {\r
+      break_point_hit_count++;\r
+      // Continue stepping until returned to bottom frame.\r
+      if (exec_state.frameCount() > 1) {\r
+        exec_state.prepareStep(Debug.StepAction.StepOut, step_out_count);\r
+      }\r
+\r
+    }\r
+  } catch(e) {\r
+    exception = e;\r
+  }\r
+\r
+};\r
+\r
+function BeginTest(name) {\r
+  test_name = name;\r
+  break_point_hit_count = 0;\r
+  exception = null;\r
+}\r
+\r
+function EndTest(expected_break_point_hit_count) {\r
+  assertEquals(expected_break_point_hit_count, break_point_hit_count, test_name);\r
+  assertNull(exception, test_name);\r
+  test_name = null;\r
+}\r
+\r
+// Add the debug event listener.\r
+Debug.setListener(listener);\r
+\r
+\r
+var shouldBreak = null;\r
+function fact(x) {\r
+  if (shouldBreak(x)) {\r
+    debugger;\r
+  }\r
+  if (x < 2) {\r
+    return 1;\r
+  } else {\r
+    return x*fact(x-1);\r
+  }\r
+}\r
+\r
+BeginTest('Test 1');\r
+shouldBreak = function(x) { return x == 3; };\r
+step_out_count = 1;\r
+fact(3);\r
+EndTest(2);\r
+\r
+BeginTest('Test 2');\r
+shouldBreak = function(x) { return x == 2; };\r
+step_out_count = 1;\r
+fact(3);\r
+EndTest(3);\r
+\r
+BeginTest('Test 3');\r
+shouldBreak = function(x) { return x == 1; };\r
+step_out_count = 2;\r
+fact(3);\r
+EndTest(2);\r
+\r
+BeginTest('Test 4');\r
+shouldBreak = function(x) { print(x); return x == 1 || x == 3; };\r
+step_out_count = 2;\r
+fact(3);\r
+EndTest(3);\r
+\r
+// Get rid of the debug event listener.\r
+Debug.setListener(null);\r
diff --git a/deps/v8/test/mjsunit/debug-stepout-to-builtin.js b/deps/v8/test/mjsunit/debug-stepout-to-builtin.js
new file mode 100644 (file)
index 0000000..486eee0
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright 2009 the V8 project authors. All rights reserved.\r
+// Redistribution and use in source and binary forms, with or without\r
+// modification, are permitted provided that the following conditions are\r
+// met:\r
+//\r
+//     * Redistributions of source code must retain the above copyright\r
+//       notice, this list of conditions and the following disclaimer.\r
+//     * Redistributions in binary form must reproduce the above\r
+//       copyright notice, this list of conditions and the following\r
+//       disclaimer in the documentation and/or other materials provided\r
+//       with the distribution.\r
+//     * Neither the name of Google Inc. nor the names of its\r
+//       contributors may be used to endorse or promote products derived\r
+//       from this software without specific prior written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+// Flags: --expose-debug-as debug\r
+\r
+// Get the Debug object exposed from the debug context global object.\r
+Debug = debug.Debug\r
+\r
+var exception = null;\r
+var state = 1;\r
+var expected_source_line_text = null;\r
+var expected_function_name = null;\r
+\r
+// Simple debug event handler which first time will cause 'step out' action\r
+// and than check that execution is paused inside function\r
+// expected_function_name.\r
+function listener(event, exec_state, event_data, data) {\r
+  try {\r
+    if (event == Debug.DebugEvent.Break) {\r
+      if (state == 1) {\r
+        exec_state.prepareStep(Debug.StepAction.StepOut, 2);\r
+        state = 2;\r
+      } else if (state == 2) {\r
+        assertEquals(expected_function_name, event_data.func().name());\r
+        assertEquals(expected_source_line_text,\r
+                     event_data.sourceLineText());\r
+        state = 3;\r
+      }\r
+    }\r
+  } catch(e) {\r
+    exception = e;\r
+  }\r
+};\r
+\r
+// Add the debug event listener.\r
+Debug.setListener(listener);\r
+\r
+var obj = {key:10};\r
+\r
+function replacer(key, value) {\r
+  if (key == 'key') {\r
+    debugger;\r
+  }\r
+  return value;\r
+}\r
+\r
+// Test step into function call from a function without local variables.\r
+function testStepOutToBuiltIn() {\r
+  expected_function_name = 'testStepOutToBuiltIn';\r
+  expected_source_line_text = '}  // expected line';\r
+  JSON.stringify(obj, replacer);\r
+}  // expected line\r
+\r
+state = 1;\r
+testStepOutToBuiltIn();\r
+assertNull(exception);\r
+assertEquals(3, state);\r
+\r
+// Get rid of the debug event listener.\r
+Debug.setListener(null);\r
index 371311e..c5a5487 100644 (file)
@@ -90,8 +90,9 @@ assertEquals(F.prototype, GetPrototypeOf(F));
 // in GetPrototypeOf and go to a monomorphic IC load instead.
 assertEquals(87, GetPrototypeOf({prototype:87}));
 
-// Check the prototype is enumerable as specified in ECMA262, 15.3.5.2
+// Check the prototype is not enumerable, for compatibility with
+// safari.  This is deliberately incompatible with ECMA262, 15.3.5.2.
 var foo = new Function("return x");
 var result  = ""
 for (var n in foo) result += n;
-assertEquals(result, "prototype");
+assertEquals(result, "");
index 6ac4938..3b89154 100644 (file)
@@ -60,8 +60,11 @@ debug-setbreakpoint: CRASH || FAIL || PASS
 debug-step-stub-callfunction: SKIP
 debug-stepin-accessor: CRASH || FAIL
 debug-stepin-builtin: CRASH || FAIL
+debug-stepin-call-function-stub: CRASH || FAIL
 debug-stepin-constructor: CRASH, FAIL
 debug-stepin-function-call: CRASH || FAIL
+debug-stepout-recursive-function: CRASH || FAIL
+debug-stepout-to-builtin: CRASH || FAIL
 debug-step: SKIP
 debug-breakpoints: PASS || FAIL
 debug-handle: CRASH || FAIL || PASS
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-18639.js b/deps/v8/test/mjsunit/regress/regress-crbug-18639.js
new file mode 100644 (file)
index 0000000..23e225a
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// See http://crbug.com/18639
+
+toString = toString;
+__defineGetter__("z", (0).toLocaleString);
+z;
+z;
+((0).toLocaleString)();
index 96840f5..97924c8 100644 (file)
@@ -31,7 +31,7 @@ from os.path import join, dirname, exists
 import re
 import tempfile
 
-
+MJSUNIT_DEBUG_FLAGS = ['--enable-slow-asserts', '--debug-code', '--verify-heap']
 FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
 FILES_PATTERN = re.compile(r"//\s+Files:(.*)")
 SELF_SCRIPT_PATTERN = re.compile(r"//\s+Env: TEST_FILE_NAME")
@@ -58,6 +58,8 @@ class MjsunitTestCase(test.TestCase):
     flags_match = FLAGS_PATTERN.search(source)
     if flags_match:
       result += flags_match.group(1).strip().split()
+    if self.mode == 'debug':
+      result += MJSUNIT_DEBUG_FLAGS
     additional_files = []
     files_match = FILES_PATTERN.search(source);
     # Accept several lines of 'Files:'
index 41395b3..9793dc8 100644 (file)
@@ -124,6 +124,10 @@ ecma/Date/15.9.5.28-1: PASS || ($ARM && FAIL)
 ecma/Array/15.4.4.5-3: PASS || ($ARM && FAIL)
 ecma/Date/15.9.5.22-2: PASS || ($ARM && FAIL)
 
+# Flaky test that fails due to what appears to be a bug in the test.
+# Occurs depending on current time
+ecma/Date/15.9.5.8: PASS || FAIL
+
 # Severely brain-damaged test. Access to local variables must not
 # be more than 2.5 times faster than access to global variables? WTF?
 js1_5/Regress/regress-169559: PASS || FAIL
index 72b3059..84f0eea 100644 (file)
@@ -476,7 +476,7 @@ UnixCppEntriesProvider.prototype.parseNextLine = function() {
 function MacCppEntriesProvider(nmExec) {
   UnixCppEntriesProvider.call(this, nmExec);
   // Note an empty group. It is required, as UnixCppEntriesProvider expects 3 groups.
-  this.FUNC_RE = /^([0-9a-fA-F]{8}) ()[iItT] (.*)$/;
+  this.FUNC_RE = /^([0-9a-fA-F]{8,16}) ()[iItT] (.*)$/;
 };
 inherits(MacCppEntriesProvider, UnixCppEntriesProvider);
 
index 3aa9374..0d6a888 100644 (file)
@@ -2,11 +2,13 @@
 <VisualStudioPropertySheet
        ProjectType="Visual C++"
        Version="8.00"
+       OutputDirectory="$(SolutionDir)$(ConfigurationName)Arm"
+       IntermediateDirectory="$(SolutionDir)$(ConfigurationName)Arm\obj\$(ProjectName)"
        Name="arm"
        >
        <Tool
                Name="VCCLCompilerTool"
-               PreprocessorDefinitions="V8_TARGET_ARCH_ARM"
+               PreprocessorDefinitions="_USE_32BIT_TIME_T;V8_TARGET_ARCH_ARM;V8_NATIVE_REGEXP"
                DisableSpecificWarnings="4996"
        />
 </VisualStudioPropertySheet>
index d23e4fc..238dd97 100644 (file)
@@ -3,8 +3,6 @@
        ProjectType="Visual C++"
        Version="8.00"
        Name="essential"
-       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-       IntermediateDirectory="$(SolutionDir)$(ConfigurationName)\obj\$(ProjectName)"
        CharacterSet="1"
        >
        <Tool
diff --git a/deps/v8/tools/visual_studio/d8_arm.vcproj b/deps/v8/tools/visual_studio/d8_arm.vcproj
new file mode 100644 (file)
index 0000000..fbebdb3
--- /dev/null
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8.00"
+       Name="d8"
+       ProjectGUID="{7E4C7D2D-A4B9-40B9-8192-22654E626F6C}"
+       RootNamespace="d8"
+       Keyword="Win32Proj"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       ConfigurationType="1"
+                       InheritedPropertySheets=".\common.vsprops;.\arm.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"
+                               AdditionalDependencies="winmm.lib Ws2_32.lib"
+                       />
+                       <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;.\arm.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"
+                               AdditionalDependencies="winmm.lib Ws2_32.lib"
+                       />
+                       <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\d8.cc"
+                       >
+               </File>
+               <File
+                       RelativePath="..\..\src\d8.h"
+                       >
+               </File>
+               <File
+                       RelativePath="..\..\src\d8-debug.cc"
+                       >
+               </File>
+               <File
+                       RelativePath="..\..\src\d8-debug.h"
+                       >
+               </File>
+               <File
+                       RelativePath="..\..\src\d8-windows.cc"
+                       >
+               </File>
+               <File
+                       RelativePath="..\..\src\d8.js"
+                       >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Processing js files..."
+                                               CommandLine=".\d8js2c.cmd ..\..\src &quot;$(IntDir)\DerivedSources&quot;"
+                                                                                               Outputs="$(IntDir)\DerivedSources\natives.cc;$(IntDir)\DerivedSources\natives-empty.cc"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCustomBuildTool"
+                                               Description="Processing js files..."
+                                               CommandLine=".\d8js2c.cmd ..\..\src &quot;$(IntDir)\DerivedSources&quot;"
+                                               Outputs="$(IntDir)\DerivedSources\natives.cc;$(IntDir)\DerivedSources\natives-empty.cc"
+                                       />
+                               </FileConfiguration>
+               </File>
+               <Filter
+                       Name="generated files"
+                       >
+                       <File
+                               RelativePath="$(IntDir)\DerivedSources\natives.cc"
+                               >
+                       </File>
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
index f48e808..0399bbb 100644 (file)
@@ -2,6 +2,8 @@
 <VisualStudioPropertySheet
        ProjectType="Visual C++"
        Version="8.00"
+       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+       IntermediateDirectory="$(SolutionDir)$(ConfigurationName)\obj\$(ProjectName)"
        Name="ia32"
        >
        <Tool
index 2dc6cf5..069ff32 100644 (file)
@@ -1,11 +1,11 @@
 Microsoft Visual Studio Solution File, Format Version 9.00
 # Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8", "v8.vcproj", "{21E22961-22BF-4493-BD3A-868F93DA5179}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8", "v8_arm.vcproj", "{21E22961-22BF-4493-BD3A-868F93DA5179}"
        ProjectSection(ProjectDependencies) = postProject
                {EC8B7909-62AF-470D-A75D-E1D89C837142} = {EC8B7909-62AF-470D-A75D-E1D89C837142}
        EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_shell_sample", "v8_shell_sample.vcproj", "{2DE20FFA-6F5E-48D9-84D8-09B044A5B119}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_shell_sample", "v8_shell_sample_arm.vcproj", "{2DE20FFA-6F5E-48D9-84D8-09B044A5B119}"
        ProjectSection(ProjectDependencies) = postProject
                {EC8B7909-62AF-470D-A75D-E1D89C837142} = {EC8B7909-62AF-470D-A75D-E1D89C837142}
                {21E22961-22BF-4493-BD3A-868F93DA5179} = {21E22961-22BF-4493-BD3A-868F93DA5179}
@@ -13,14 +13,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_shell_sample", "v8_shell
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{E131F77D-B713-48F3-B86D-097ECDCC4C3A}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_process_sample", "v8_process_sample.vcproj", "{EF019874-D38A-40E3-B17C-DB5923F0A79C}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_process_sample", "v8_process_sample_arm.vcproj", "{EF019874-D38A-40E3-B17C-DB5923F0A79C}"
        ProjectSection(ProjectDependencies) = postProject
                {21E22961-22BF-4493-BD3A-868F93DA5179} = {21E22961-22BF-4493-BD3A-868F93DA5179}
        EndProjectSection
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{AD933CE2-1303-448E-89C8-60B1FDD18EC3}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d8", "d8.vcproj", "{7E4C7D2D-A4B9-40B9-8192-22654E626F6C}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d8", "d8_arm.vcproj", "{7E4C7D2D-A4B9-40B9-8192-22654E626F6C}"
        ProjectSection(ProjectDependencies) = postProject
                {21E22961-22BF-4493-BD3A-868F93DA5179} = {21E22961-22BF-4493-BD3A-868F93DA5179}
        EndProjectSection
diff --git a/deps/v8/tools/visual_studio/v8_arm.vcproj b/deps/v8/tools/visual_studio/v8_arm.vcproj
new file mode 100644 (file)
index 0000000..f8cbcc4
--- /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;.\arm.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;.\arm.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\json-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 &quot;$(IntDir)\DerivedSources&quot;"
+                                               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;..\..\src\json-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 &quot;$(IntDir)\DerivedSources&quot;"
+                                               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;..\..\src\json-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>
+               </Filter>
+               <File
+                       RelativePath="..\..\src\snapshot-empty.cc"
+                       >
+               </File>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
index 8fe54af..ee8e339 100644 (file)
                                >
                        </File>
                        <File
+                               RelativePath="..\..\src\arm\constants-arm.cc"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\src\arm\constants-arm.h"
                                >
                        </File>
index a027a84..bd49f3b 100644 (file)
@@ -49,6 +49,7 @@
                        />
                        <Tool
                                Name="VCLinkerTool"
+                               AdditionalDependencies="winmm.lib Ws2_32.lib"
                        />
                        <Tool
                                Name="VCALinkTool"
                        />
                        <Tool
                                Name="VCLinkerTool"
+                               AdditionalDependencies="winmm.lib Ws2_32.lib"
                        />
                        <Tool
                                Name="VCALinkTool"
diff --git a/deps/v8/tools/visual_studio/v8_process_sample_arm.vcproj b/deps/v8/tools/visual_studio/v8_process_sample_arm.vcproj
new file mode 100644 (file)
index 0000000..7320231
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8.00"
+       Name="v8_process_sample"
+       ProjectGUID="{EF019874-D38A-40E3-B17C-DB5923F0A79C}"
+       RootNamespace="v8_process_sample"
+       Keyword="Win32Proj"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       ConfigurationType="1"
+                       InheritedPropertySheets=".\common.vsprops;.\arm.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"
+                               AdditionalDependencies="winmm.lib Ws2_32.lib"
+                       />
+                       <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;.\arm.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"
+                               AdditionalDependencies="winmm.lib Ws2_32.lib"
+                       />
+                       <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="..\..\samples\process.cc"
+                       >
+               </File>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/deps/v8/tools/visual_studio/v8_shell_sample_arm.vcproj b/deps/v8/tools/visual_studio/v8_shell_sample_arm.vcproj
new file mode 100644 (file)
index 0000000..ba7e0e0
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8.00"
+       Name="v8_shell_sample"
+       ProjectGUID="{2DE20FFA-6F5E-48D9-84D8-09B044A5B119}"
+       RootNamespace="v8_shell_sample"
+       Keyword="Win32Proj"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       ConfigurationType="1"
+                       InheritedPropertySheets=".\common.vsprops;.\arm.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"
+                               AdditionalDependencies="winmm.lib Ws2_32.lib"
+                       />
+                       <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;.\arm.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"
+                               AdditionalDependencies="winmm.lib Ws2_32.lib"
+                       />
+                       <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="..\..\samples\shell.cc"
+                       >
+               </File>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
index af0e47c..7587acf 100644 (file)
@@ -2,6 +2,8 @@
 <VisualStudioPropertySheet
        ProjectType="Visual C++"
        Version="8.00"
+       OutputDirectory="$(SolutionDir)$(ConfigurationName)64"
+       IntermediateDirectory="$(SolutionDir)$(ConfigurationName)64\obj\$(ProjectName)"
        Name="x64"
        >
        <Tool