Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Version 3.8.5

Fix broken test that assumes that no GC can clear the regexp cache (GC can happen at any time due to Crankshaft).

Fix handling of bogus receivers for Harmony collections. (issue 1884)

Add netbsd support to gyp build.

Determine page size at runtime on posix platforms.

Ensure that store buffer filtering hash sets are cleared after StoreBuffer::Filter.

Randomize the seed used for string hashing.  This helps guard against CPU-eating DOS attacks against node.js servers.  Based on code from Bert Belder.  This version only solves the issue for those that compile V8 themselves or those that do not use snapshots.  A snapshot-based precompiled V8 will still have predictable string hash codes.

Implement callback when script finishes running in V8 API.

Improve performance of Math.min and Math.max for the case of two arguments. (issue 1325)

git-svn-id: https://v8.googlecode.com/svn/trunk@10346 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
  • Loading branch information...
commit 6abdceadd60d8d2a0561074f5f6c5782f76a9cb6 1 parent 0bd7cae
authored January 05, 2012

Showing 46 changed files with 810 additions and 220 deletions. Show diff stats Hide diff stats

  1. 26  ChangeLog
  2. 6  LICENSE
  3. 15  build/common.gypi
  4. 24  build/standalone.gypi
  5. 20  include/v8.h
  6. 40  src/api.cc
  7. 11  src/arm/builtins-arm.cc
  8. 6  src/arm/code-stubs-arm.cc
  9. 20  src/checks.h
  10. 44  src/collection.js
  11. 3  src/d8-posix.cc
  12. 4  src/d8.gyp
  13. 8  src/flag-definitions.h
  14. 16  src/heap.cc
  15. 10  src/heap.h
  16. 3  src/ia32/builtins-ia32.cc
  17. 22  src/ia32/code-stubs-ia32.cc
  18. 22  src/isolate.h
  19. 3  src/macros.py
  20. 34  src/math.js
  21. 69  src/mips/builtins-mips.cc
  22. 16  src/mips/code-stubs-mips.cc
  23. 12  src/mips/lithium-codegen-mips.cc
  24. 3  src/mips/lithium-codegen-mips.h
  25. 18  src/mips/lithium-gap-resolver-mips.cc
  26. 8  src/mips/macro-assembler-mips.h
  27. 19  src/objects-inl.h
  28. 82  src/objects.cc
  29. 13  src/objects.h
  30. 21  src/platform-openbsd.cc
  31. 3  src/platform-posix.cc
  32. 13  src/profile-generator.cc
  33. 24  src/runtime.cc
  34. 37  src/spaces.cc
  35. 4  src/store-buffer.cc
  36. 39  src/v8.cc
  37. 6  src/v8.h
  38. 4  src/version.cc
  39. 11  src/x64/builtins-x64.cc
  40. 11  src/x64/code-stubs-x64.cc
  41. 97  test/cctest/test-api.cc
  42. 10  test/mjsunit/debug-evaluate-locals-optimized-double.js
  43. 12  test/mjsunit/debug-evaluate-locals-optimized.js
  44. 34  test/mjsunit/harmony/collections.js
  45. 114  tools/grokdump.py
  46. 13  tools/gyp/v8.gyp
26  ChangeLog
... ...
@@ -1,3 +1,29 @@
  1
+2012-01-05: Version 3.8.5
  2
+
  3
+        Fix broken test that assumes that no GC can clear the regexp cache (GC
  4
+        can happen at any time due to Crankshaft).
  5
+
  6
+        Fix handling of bogus receivers for Harmony collections. (issue 1884)
  7
+
  8
+        Add netbsd support to gyp build.
  9
+
  10
+        Determine page size at runtime on posix platforms.
  11
+
  12
+        Ensure that store buffer filtering hash sets are cleared after
  13
+        StoreBuffer::Filter.
  14
+
  15
+        Randomize the seed used for string hashing.  This helps guard against
  16
+        CPU-eating DOS attacks against node.js servers.  Based on code from
  17
+        Bert Belder.  This version only solves the issue for those that compile
  18
+        V8 themselves or those that do not use snapshots.  A snapshot-based
  19
+        precompiled V8 will still have predictable string hash codes.
  20
+
  21
+        Implement callback when script finishes running in V8 API.
  22
+
  23
+        Improve performance of Math.min and Math.max for the case of two
  24
+        arguments. (issue 1325)
  25
+
  26
+
1 27
 2012-01-02: Version 3.8.4
2 28
 
3 29
         Performance improvements for large Smi-only arrays.
6  LICENSE
@@ -14,7 +14,9 @@ are:
14 14
 
15 15
   - Strongtalk assembler, the basis of the files assembler-arm-inl.h,
16 16
     assembler-arm.cc, assembler-arm.h, assembler-ia32-inl.h,
17  
-    assembler-ia32.cc, assembler-ia32.h, assembler.cc and assembler.h.
  17
+    assembler-ia32.cc, assembler-ia32.h, assembler-x64-inl.h,
  18
+    assembler-x64.cc, assembler-x64.h, assembler-mips-inl.h,
  19
+    assembler-mips.cc, assembler-mips.h, assembler.cc and assembler.h.
18 20
     This code is copyrighted by Sun Microsystems Inc. and released
19 21
     under a 3-clause BSD license.
20 22
 
@@ -24,7 +26,7 @@ are:
24 26
 These libraries have their own licenses; we recommend you read them,
25 27
 as their terms may differ from the terms below.
26 28
 
27  
-Copyright 2006-2011, the V8 project authors. All rights reserved.
  29
+Copyright 2006-2012, the V8 project authors. All rights reserved.
28 30
 Redistribution and use in source and binary forms, with or without
29 31
 modification, are permitted provided that the following conditions are
30 32
 met:
15  build/common.gypi
... ...
@@ -1,4 +1,4 @@
1  
-# Copyright 2011 the V8 project authors. All rights reserved.
  1
+# Copyright 2012 the V8 project authors. All rights reserved.
2 2
 # Redistribution and use in source and binary forms, with or without
3 3
 # modification, are permitted provided that the following conditions are
4 4
 # met:
@@ -215,7 +215,8 @@
215 215
           },
216 216
         },
217 217
       }],
218  
-      ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
  218
+      ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
  219
+         or OS=="netbsd"', {
219 220
         'conditions': [
220 221
           [ 'target_arch=="ia32"', {
221 222
             'cflags': [ '-m32' ],
@@ -259,7 +260,10 @@
259 260
           ['OS=="freebsd" or OS=="openbsd"', {
260 261
             'cflags': [ '-I/usr/local/include' ],
261 262
           }],
262  
-          ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
  263
+          ['OS=="netbsd"', {
  264
+            'cflags': [ '-I/usr/pkg/include' ],
  265
+          }],
  266
+          ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
263 267
             'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter',
264 268
                         '-Wnon-virtual-dtor' ],
265 269
           }],
@@ -267,7 +271,7 @@
267 271
       },
268 272
       'Release': {
269 273
         'conditions': [
270  
-          ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
  274
+          ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
271 275
             'cflags!': [
272 276
               '-O2',
273 277
               '-Os',
@@ -290,6 +294,9 @@
290 294
           ['OS=="freebsd" or OS=="openbsd"', {
291 295
             'cflags': [ '-I/usr/local/include' ],
292 296
           }],
  297
+          ['OS=="netbsd"', {
  298
+            'cflags': [ '-I/usr/pkg/include' ],
  299
+          }],
293 300
           ['OS=="mac"', {
294 301
             'xcode_settings': {
295 302
               'GCC_OPTIMIZATION_LEVEL': '3',  # -O3
24  build/standalone.gypi
... ...
@@ -1,4 +1,4 @@
1  
-# Copyright 2011 the V8 project authors. All rights reserved.
  1
+# Copyright 2012 the V8 project authors. All rights reserved.
2 2
 # Redistribution and use in source and binary forms, with or without
3 3
 # modification, are permitted provided that the following conditions are
4 4
 # met:
@@ -37,13 +37,16 @@
37 37
       'variables': {
38 38
         'variables': {
39 39
           'conditions': [
40  
-            [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
41  
-              # This handles the Linux platforms we generally deal with. Anything
42  
-              # else gets passed through, which probably won't work very well; such
43  
-              # hosts should pass an explicit target_arch to gyp.
  40
+            ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
  41
+              # This handles the Linux platforms we generally deal with.
  42
+              # Anything else gets passed through, which probably won't work
  43
+              # very well; such hosts should pass an explicit target_arch
  44
+              # to gyp.
44 45
               'host_arch%':
45  
-                '<!(uname -m | sed -e "s/i.86/ia32/;s/x86_64/x64/;s/amd64/x64/;s/arm.*/arm/;s/mips.*/mips/")',
46  
-            }, {  # OS!="linux" and OS!="freebsd" and OS!="openbsd"
  46
+                '<!(uname -m | sed -e "s/i.86/ia32/;\
  47
+                  s/x86_64/x64/;s/amd64/x64/;s/arm.*/arm/;s/mips.*/mips/")',
  48
+            }, {
  49
+              # OS!="linux" and OS!="freebsd" and OS!="openbsd" and OS!="netbsd"
47 50
               'host_arch%': 'ia32',
48 51
             }],
49 52
           ],
@@ -78,7 +81,8 @@
78 81
     },
79 82
   },
80 83
   'conditions': [
81  
-    [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
  84
+    ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
  85
+       or OS=="netbsd"', {
82 86
       'target_defaults': {
83 87
         'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter',
84 88
                     '-Wnon-virtual-dtor', '-pthread', '-fno-rtti',
@@ -96,7 +100,9 @@
96 100
           }],
97 101
         ],
98 102
       },
99  
-    }],  # 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"'
  103
+    }],
  104
+    # 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"
  105
+    #  or OS=="netbsd"'
100 106
     ['OS=="win"', {
101 107
       'target_defaults': {
102 108
         'defines': [
20  include/v8.h
@@ -2635,6 +2635,9 @@ typedef void (*MemoryAllocationCallback)(ObjectSpace space,
2635 2635
                                          AllocationAction action,
2636 2636
                                          int size);
2637 2637
 
  2638
+// --- Leave Script Callback ---
  2639
+typedef void (*CallCompletedCallback)();
  2640
+
2638 2641
 // --- Failed Access Check Callback ---
2639 2642
 typedef void (*FailedAccessCheckCallback)(Local<Object> target,
2640 2643
                                           AccessType type,
@@ -3033,12 +3036,25 @@ class V8EXPORT V8 {
3033 3036
                                           AllocationAction action);
3034 3037
 
3035 3038
   /**
3036  
-   * This function removes callback which was installed by
3037  
-   * AddMemoryAllocationCallback function.
  3039
+   * Removes callback that was installed by AddMemoryAllocationCallback.
3038 3040
    */
3039 3041
   static void RemoveMemoryAllocationCallback(MemoryAllocationCallback callback);
3040 3042
 
3041 3043
   /**
  3044
+   * Adds a callback to notify the host application when a script finished
  3045
+   * running.  If a script re-enters the runtime during executing, the
  3046
+   * CallCompletedCallback is only invoked when the outer-most script
  3047
+   * execution ends.  Executing scripts inside the callback do not trigger
  3048
+   * further callbacks.
  3049
+   */
  3050
+  static void AddCallCompletedCallback(CallCompletedCallback callback);
  3051
+
  3052
+  /**
  3053
+   * Removes callback that was installed by AddCallCompletedCallback.
  3054
+   */
  3055
+  static void RemoveCallCompletedCallback(CallCompletedCallback callback);
  3056
+
  3057
+  /**
3042 3058
    * Allows the host application to group objects together. If one
3043 3059
    * object in the group is alive, all objects in the group are alive.
3044 3060
    * After each garbage collection, object groups are removed. It is
40  src/api.cc
@@ -78,7 +78,7 @@ namespace v8 {
78 78
   bool has_pending_exception = false
79 79
 
80 80
 
81  
-#define EXCEPTION_BAILOUT_CHECK(isolate, value)                                \
  81
+#define EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, do_callback)           \
82 82
   do {                                                                         \
83 83
     i::HandleScopeImplementer* handle_scope_implementer =                      \
84 84
         (isolate)->handle_scope_implementer();                                 \
@@ -91,11 +91,22 @@ namespace v8 {
91 91
       }                                                                        \
92 92
       bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();   \
93 93
       (isolate)->OptionalRescheduleException(call_depth_is_zero);              \
  94
+      do_callback                                                              \
94 95
       return value;                                                            \
95 96
     }                                                                          \
  97
+    do_callback                                                                \
96 98
   } while (false)
97 99
 
98 100
 
  101
+#define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value)                    \
  102
+  EXCEPTION_BAILOUT_CHECK_GENERIC(                                             \
  103
+      isolate, value, i::V8::FireCallCompletedCallback(isolate);)
  104
+
  105
+
  106
+#define EXCEPTION_BAILOUT_CHECK(isolate, value)                                \
  107
+  EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;)
  108
+
  109
+
99 110
 #define API_ENTRY_CHECK(isolate, msg)                                          \
100 111
   do {                                                                         \
101 112
     if (v8::Locker::IsActive()) {                                              \
@@ -1568,7 +1579,7 @@ Local<Value> Script::Run() {
1568 1579
         isolate->context()->global_proxy(), isolate);
1569 1580
     i::Handle<i::Object> result =
1570 1581
         i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
1571  
-    EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
  1582
+    EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
1572 1583
     raw_result = *result;
1573 1584
   }
1574 1585
   i::Handle<i::Object> result(raw_result, isolate);
@@ -3494,7 +3505,7 @@ Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv,
3494 3505
   EXCEPTION_PREAMBLE(isolate);
3495 3506
   i::Handle<i::Object> returned =
3496 3507
       i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
3497  
-  EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
  3508
+  EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
3498 3509
   return Utils::ToLocal(scope.CloseAndEscape(returned));
3499 3510
 }
3500 3511
 
@@ -3515,7 +3526,7 @@ Local<v8::Value> Object::CallAsConstructor(int argc,
3515 3526
     EXCEPTION_PREAMBLE(isolate);
3516 3527
     i::Handle<i::Object> returned =
3517 3528
         i::Execution::New(fun, argc, args, &has_pending_exception);
3518  
-    EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
  3529
+    EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
3519 3530
     return Utils::ToLocal(scope.CloseAndEscape(
3520 3531
         i::Handle<i::JSObject>::cast(returned)));
3521 3532
   }
@@ -3528,7 +3539,7 @@ Local<v8::Value> Object::CallAsConstructor(int argc,
3528 3539
     EXCEPTION_PREAMBLE(isolate);
3529 3540
     i::Handle<i::Object> returned =
3530 3541
         i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
3531  
-    EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
  3542
+    EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
3532 3543
     ASSERT(!delegate->IsUndefined());
3533 3544
     return Utils::ToLocal(scope.CloseAndEscape(returned));
3534 3545
   }
@@ -3555,7 +3566,7 @@ Local<v8::Object> Function::NewInstance(int argc,
3555 3566
   EXCEPTION_PREAMBLE(isolate);
3556 3567
   i::Handle<i::Object> returned =
3557 3568
       i::Execution::New(function, argc, args, &has_pending_exception);
3558  
-  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
  3569
+  EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
3559 3570
   return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
3560 3571
 }
3561 3572
 
@@ -3576,7 +3587,7 @@ Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
3576 3587
     EXCEPTION_PREAMBLE(isolate);
3577 3588
     i::Handle<i::Object> returned =
3578 3589
         i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
3579  
-    EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
  3590
+    EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
3580 3591
     raw_result = *returned;
3581 3592
   }
3582 3593
   i::Handle<i::Object> result(raw_result);
@@ -5045,6 +5056,21 @@ void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
5045 5056
 }
5046 5057
 
5047 5058
 
  5059
+void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
  5060
+  if (callback == NULL) return;
  5061
+  i::Isolate* isolate = i::Isolate::Current();
  5062
+  if (IsDeadCheck(isolate, "v8::V8::AddLeaveScriptCallback()")) return;
  5063
+  i::V8::AddCallCompletedCallback(callback);
  5064
+}
  5065
+
  5066
+
  5067
+void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
  5068
+  i::Isolate* isolate = i::Isolate::Current();
  5069
+  if (IsDeadCheck(isolate, "v8::V8::RemoveLeaveScriptCallback()")) return;
  5070
+  i::V8::RemoveCallCompletedCallback(callback);
  5071
+}
  5072
+
  5073
+
5048 5074
 void V8::PauseProfiler() {
5049 5075
   i::Isolate* isolate = i::Isolate::Current();
5050 5076
   isolate->logger()->PauseProfiler();
11  src/arm/builtins-arm.cc
... ...
@@ -1,4 +1,4 @@
1  
-// Copyright 2011 the V8 project authors. All rights reserved.
  1
+// Copyright 2012 the V8 project authors. All rights reserved.
2 2
 // Redistribution and use in source and binary forms, with or without
3 3
 // modification, are permitted provided that the following conditions are
4 4
 // met:
@@ -316,7 +316,8 @@ static void AllocateJSArray(MacroAssembler* masm,
316 316
 static void ArrayNativeCode(MacroAssembler* masm,
317 317
                             Label* call_generic_code) {
318 318
   Counters* counters = masm->isolate()->counters();
319  
-  Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array;
  319
+  Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array,
  320
+      has_non_smi_element;
320 321
 
321 322
   // Check for array construction with zero arguments or one.
322 323
   __ cmp(r0, Operand(0, RelocInfo::NONE));
@@ -415,7 +416,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
415 416
   __ bind(&loop);
416 417
   __ ldr(r2, MemOperand(r7, kPointerSize, PostIndex));
417 418
   if (FLAG_smi_only_arrays) {
418  
-    __ JumpIfNotSmi(r2, call_generic_code);
  419
+    __ JumpIfNotSmi(r2, &has_non_smi_element);
419 420
   }
420 421
   __ str(r2, MemOperand(r5, -kPointerSize, PreIndex));
421 422
   __ bind(&entry);
@@ -431,6 +432,10 @@ static void ArrayNativeCode(MacroAssembler* masm,
431 432
   __ add(sp, sp, Operand(kPointerSize));
432 433
   __ mov(r0, r3);
433 434
   __ Jump(lr);
  435
+
  436
+  __ bind(&has_non_smi_element);
  437
+  __ UndoAllocationInNewSpace(r3, r4);
  438
+  __ b(call_generic_code);
434 439
 }
435 440
 
436 441
 
6  src/arm/code-stubs-arm.cc
@@ -5730,7 +5730,11 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
5730 5730
                                     Register hash,
5731 5731
                                     Register character) {
5732 5732
   // hash = character + (character << 10);
5733  
-  __ add(hash, character, Operand(character, LSL, 10));
  5733
+  __ LoadRoot(hash, Heap::kStringHashSeedRootIndex);
  5734
+  // Untag smi seed and add the character.
  5735
+  __ add(hash, character, Operand(hash, LSR, kSmiTagSize));
  5736
+  // hash += hash << 10;
  5737
+  __ add(hash, hash, Operand(hash, LSL, 10));
5734 5738
   // hash ^= hash >> 6;
5735 5739
   __ eor(hash, hash, Operand(hash, LSR, 6));
5736 5740
 }
20  src/checks.h
... ...
@@ -1,4 +1,4 @@
1  
-// Copyright 2011 the V8 project authors. All rights reserved.
  1
+// Copyright 2012 the V8 project authors. All rights reserved.
2 2
 // Redistribution and use in source and binary forms, with or without
3 3
 // modification, are permitted provided that the following conditions are
4 4
 // met:
@@ -265,16 +265,16 @@ extern bool FLAG_enable_slow_asserts;
265 265
 // The ASSERT macro is equivalent to CHECK except that it only
266 266
 // generates code in debug builds.
267 267
 #ifdef DEBUG
268  
-#define ASSERT_RESULT(expr)  CHECK(expr)
269  
-#define ASSERT(condition)    CHECK(condition)
270  
-#define ASSERT_EQ(v1, v2)    CHECK_EQ(v1, v2)
271  
-#define ASSERT_NE(v1, v2)    CHECK_NE(v1, v2)
272  
-#define ASSERT_GE(v1, v2)    CHECK_GE(v1, v2)
273  
-#define ASSERT_LT(v1, v2)    CHECK_LT(v1, v2)
274  
-#define ASSERT_LE(v1, v2)    CHECK_LE(v1, v2)
275  
-#define SLOW_ASSERT(condition) if (FLAG_enable_slow_asserts) CHECK(condition)
  268
+#define ASSERT_RESULT(expr)    CHECK(expr)
  269
+#define ASSERT(condition)      CHECK(condition)
  270
+#define ASSERT_EQ(v1, v2)      CHECK_EQ(v1, v2)
  271
+#define ASSERT_NE(v1, v2)      CHECK_NE(v1, v2)
  272
+#define ASSERT_GE(v1, v2)      CHECK_GE(v1, v2)
  273
+#define ASSERT_LT(v1, v2)      CHECK_LT(v1, v2)
  274
+#define ASSERT_LE(v1, v2)      CHECK_LE(v1, v2)
  275
+#define SLOW_ASSERT(condition) CHECK(!FLAG_enable_slow_asserts || (condition))
276 276
 #else
277  
-#define ASSERT_RESULT(expr)     (expr)
  277
+#define ASSERT_RESULT(expr)    (expr)
278 278
 #define ASSERT(condition)      ((void) 0)
279 279
 #define ASSERT_EQ(v1, v2)      ((void) 0)
280 280
 #define ASSERT_NE(v1, v2)      ((void) 0)
44  src/collection.js
@@ -47,6 +47,10 @@ function SetConstructor() {
47 47
 
48 48
 
49 49
 function SetAdd(key) {
  50
+  if (!IS_SET(this)) {
  51
+    throw MakeTypeError('incompatible_method_receiver',
  52
+                        ['Set.prototype.add', this]);
  53
+  }
50 54
   if (IS_UNDEFINED(key)) {
51 55
     key = undefined_sentinel;
52 56
   }
@@ -55,6 +59,10 @@ function SetAdd(key) {
55 59
 
56 60
 
57 61
 function SetHas(key) {
  62
+  if (!IS_SET(this)) {
  63
+    throw MakeTypeError('incompatible_method_receiver',
  64
+                        ['Set.prototype.has', this]);
  65
+  }
58 66
   if (IS_UNDEFINED(key)) {
59 67
     key = undefined_sentinel;
60 68
   }
@@ -63,6 +71,10 @@ function SetHas(key) {
63 71
 
64 72
 
65 73
 function SetDelete(key) {
  74
+  if (!IS_SET(this)) {
  75
+    throw MakeTypeError('incompatible_method_receiver',
  76
+                        ['Set.prototype.delete', this]);
  77
+  }
66 78
   if (IS_UNDEFINED(key)) {
67 79
     key = undefined_sentinel;
68 80
   }
@@ -80,6 +92,10 @@ function MapConstructor() {
80 92
 
81 93
 
82 94
 function MapGet(key) {
  95
+  if (!IS_MAP(this)) {
  96
+    throw MakeTypeError('incompatible_method_receiver',
  97
+                        ['Map.prototype.get', this]);
  98
+  }
83 99
   if (IS_UNDEFINED(key)) {
84 100
     key = undefined_sentinel;
85 101
   }
@@ -88,6 +104,10 @@ function MapGet(key) {
88 104
 
89 105
 
90 106
 function MapSet(key, value) {
  107
+  if (!IS_MAP(this)) {
  108
+    throw MakeTypeError('incompatible_method_receiver',
  109
+                        ['Map.prototype.set', this]);
  110
+  }
91 111
   if (IS_UNDEFINED(key)) {
92 112
     key = undefined_sentinel;
93 113
   }
@@ -96,6 +116,10 @@ function MapSet(key, value) {
96 116
 
97 117
 
98 118
 function MapHas(key) {
  119
+  if (!IS_MAP(this)) {
  120
+    throw MakeTypeError('incompatible_method_receiver',
  121
+                        ['Map.prototype.has', this]);
  122
+  }
99 123
   if (IS_UNDEFINED(key)) {
100 124
     key = undefined_sentinel;
101 125
   }
@@ -104,6 +128,10 @@ function MapHas(key) {
104 128
 
105 129
 
106 130
 function MapDelete(key) {
  131
+  if (!IS_MAP(this)) {
  132
+    throw MakeTypeError('incompatible_method_receiver',
  133
+                        ['Map.prototype.delete', this]);
  134
+  }
107 135
   if (IS_UNDEFINED(key)) {
108 136
     key = undefined_sentinel;
109 137
   }
@@ -126,6 +154,10 @@ function WeakMapConstructor() {
126 154
 
127 155
 
128 156
 function WeakMapGet(key) {
  157
+  if (!IS_WEAKMAP(this)) {
  158
+    throw MakeTypeError('incompatible_method_receiver',
  159
+                        ['WeakMap.prototype.get', this]);
  160
+  }
129 161
   if (!IS_SPEC_OBJECT(key)) {
130 162
     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
131 163
   }
@@ -134,6 +166,10 @@ function WeakMapGet(key) {
134 166
 
135 167
 
136 168
 function WeakMapSet(key, value) {
  169
+  if (!IS_WEAKMAP(this)) {
  170
+    throw MakeTypeError('incompatible_method_receiver',
  171
+                        ['WeakMap.prototype.set', this]);
  172
+  }
137 173
   if (!IS_SPEC_OBJECT(key)) {
138 174
     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
139 175
   }
@@ -142,6 +178,10 @@ function WeakMapSet(key, value) {
142 178
 
143 179
 
144 180
 function WeakMapHas(key) {
  181
+  if (!IS_WEAKMAP(this)) {
  182
+    throw MakeTypeError('incompatible_method_receiver',
  183
+                        ['WeakMap.prototype.has', this]);
  184
+  }
145 185
   if (!IS_SPEC_OBJECT(key)) {
146 186
     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
147 187
   }
@@ -150,6 +190,10 @@ function WeakMapHas(key) {
150 190
 
151 191
 
152 192
 function WeakMapDelete(key) {
  193
+  if (!IS_WEAKMAP(this)) {
  194
+    throw MakeTypeError('incompatible_method_receiver',
  195
+                        ['WeakMap.prototype.delete', this]);
  196
+  }
153 197
   if (!IS_SPEC_OBJECT(key)) {
154 198
     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
155 199
   }
3  src/d8-posix.cc
@@ -366,7 +366,8 @@ static Handle<Value> GetStdout(int child_fd,
366 366
 // We're disabling usage of waitid in Mac OS X because it doens't work for us:
367 367
 // a parent process hangs on waiting while a child process is already a zombie.
368 368
 // See http://code.google.com/p/v8/issues/detail?id=401.
369  
-#if defined(WNOWAIT) && !defined(ANDROID) && !defined(__APPLE__)
  369
+#if defined(WNOWAIT) && !defined(ANDROID) && !defined(__APPLE__) \
  370
+    && !defined(__NetBSD__)
370 371
 #if !defined(__FreeBSD__)
371 372
 #define HAS_WAITID 1
372 373
 #endif
4  src/d8.gyp
@@ -64,8 +64,8 @@
64 64
               'libraries': [ '-lreadline', ],
65 65
               'sources': [ 'd8-readline.cc' ],
66 66
             }],
67  
-            [ '(OS=="linux" or OS=="mac" or OS=="freebsd" \
68  
-              or OS=="openbsd" or OS=="solaris" or OS=="android")', {
  67
+            ['(OS=="linux" or OS=="mac" or OS=="freebsd" or OS=="netbsd" \
  68
+               or OS=="openbsd" or OS=="solaris" or OS=="android")', {
69 69
               'sources': [ 'd8-posix.cc', ]
70 70
             }],
71 71
             [ 'OS=="win"', {
8  src/flag-definitions.h
@@ -349,6 +349,14 @@ DEFINE_bool(trace_exception, false,
349 349
             "print stack trace when throwing exceptions")
350 350
 DEFINE_bool(preallocate_message_memory, false,
351 351
             "preallocate some memory to build stack traces.")
  352
+DEFINE_bool(randomize_string_hashes,
  353
+            true,
  354
+            "randomize string hashes to avoid predictable hash collisions "
  355
+            "(with snapshots this option cannot override the baked-in seed)")
  356
+DEFINE_int(string_hash_seed,
  357
+           0,
  358
+           "Fixed seed to use to string hashing (0 means random)"
  359
+           "(with snapshots this option cannot override the baked-in seed)")
352 360
 
353 361
 // v8.cc
354 362
 DEFINE_bool(preemption, false,
16  src/heap.cc
@@ -2318,6 +2318,10 @@ bool Heap::CreateInitialObjects() {
2318 2318
   }
2319 2319
   set_infinity_value(HeapNumber::cast(obj));
2320 2320
 
  2321
+  // The hole has not been created yet, but we want to put something
  2322
+  // predictable in the gaps in the symbol table, so lets make that Smi zero.
  2323
+  set_the_hole_value(reinterpret_cast<Oddball*>(Smi::FromInt(0)));
  2324
+
2321 2325
   // Allocate initial symbol table.
2322 2326
   { MaybeObject* maybe_obj = SymbolTable::Allocate(kInitialSymbolTableSize);
2323 2327
     if (!maybe_obj->ToObject(&obj)) return false;
@@ -5638,6 +5642,18 @@ bool Heap::Setup(bool create_heap_objects) {
5638 5642
   lo_space_ = new LargeObjectSpace(this, max_old_generation_size_, LO_SPACE);
5639 5643
   if (lo_space_ == NULL) return false;
5640 5644
   if (!lo_space_->Setup()) return false;
  5645
+
  5646
+  // Setup the seed that is used to randomize the string hash function.
  5647
+  ASSERT(string_hash_seed() == 0);
  5648
+  if (FLAG_randomize_string_hashes) {
  5649
+    if (FLAG_string_hash_seed == 0) {
  5650
+      set_string_hash_seed(
  5651
+          Smi::FromInt(V8::RandomPrivate(isolate()) & 0x3fffffff));
  5652
+    } else {
  5653
+      set_string_hash_seed(Smi::FromInt(FLAG_string_hash_seed));
  5654
+    }
  5655
+  }
  5656
+
5641 5657
   if (create_heap_objects) {
5642 5658
     // Create initial maps.
5643 5659
     if (!CreateInitialMaps()) return false;
10  src/heap.h
@@ -96,6 +96,7 @@ inline Heap* _inline_get_heap_();
96 96
   V(FixedArray, single_character_string_cache, SingleCharacterStringCache)     \
97 97
   V(FixedArray, string_split_cache, StringSplitCache)                          \
98 98
   V(Object, termination_exception, TerminationException)                       \
  99
+  V(Smi, string_hash_seed, StringHashSeed)                                     \
99 100
   V(Map, string_map, StringMap)                                                \
100 101
   V(Map, symbol_map, SymbolMap)                                                \
101 102
   V(Map, cons_string_map, ConsStringMap)                                       \
@@ -954,8 +955,7 @@ class Heap {
954 955
   // Please note this function does not perform a garbage collection.
955 956
   MUST_USE_RESULT MaybeObject* LookupSymbol(Vector<const char> str);
956 957
   MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str);
957  
-  MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(
958  
-      Vector<const uc16> str);
  958
+  MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(Vector<const uc16> str);
959 959
   MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(const char* str) {
960 960
     return LookupSymbol(CStrVector(str));
961 961
   }
@@ -1506,6 +1506,12 @@ class Heap {
1506 1506
     return idle_notification_will_schedule_next_gc_;
1507 1507
   }
1508 1508
 
  1509
+  uint32_t StringHashSeed() {
  1510
+    uint32_t seed = static_cast<uint32_t>(string_hash_seed()->value());
  1511
+    ASSERT(FLAG_randomize_string_hashes || seed == 0);
  1512
+    return seed;
  1513
+  }
  1514
+
1509 1515
  private:
1510 1516
   Heap();
1511 1517
 
3  src/ia32/builtins-ia32.cc
... ...
@@ -1,4 +1,4 @@
1  
-// Copyright 2011 the V8 project authors. All rights reserved.
  1
+// Copyright 2012 the V8 project authors. All rights reserved.
2 2
 // Redistribution and use in source and binary forms, with or without
3 3
 // modification, are permitted provided that the following conditions are
4 4
 // met:
@@ -1297,6 +1297,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
1297 1297
   __ bind(&has_non_smi_element);
1298 1298
   // Throw away the array that's only been partially constructed.
1299 1299
   __ pop(eax);
  1300
+  __ UndoAllocationInNewSpace(eax);
1300 1301
 
1301 1302
   // Restore argc and constructor before running the generic code.
1302 1303
   __ bind(&prepare_generic_code_call);
22  src/ia32/code-stubs-ia32.cc
@@ -6033,10 +6033,24 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
6033 6033
                                     Register hash,
6034 6034
                                     Register character,
6035 6035
                                     Register scratch) {
6036  
-  // hash = character + (character << 10);
6037  
-  __ mov(hash, character);
6038  
-  __ shl(hash, 10);
6039  
-  __ add(hash, character);
  6036
+  // hash = (seed + character) + ((seed + character) << 10);
  6037
+  if (Serializer::enabled()) {
  6038
+    ExternalReference roots_array_start =
  6039
+        ExternalReference::roots_array_start(masm->isolate());
  6040
+    __ mov(scratch, Immediate(Heap::kStringHashSeedRootIndex));
  6041
+    __ mov(scratch, Operand::StaticArray(scratch,
  6042
+                                         times_pointer_size,
  6043
+                                         roots_array_start));
  6044
+    __ add(scratch, character);
  6045
+    __ mov(hash, scratch);
  6046
+    __ shl(scratch, 10);
  6047
+    __ add(hash, scratch);
  6048
+  } else {
  6049
+    int32_t seed = masm->isolate()->heap()->StringHashSeed();
  6050
+    __ lea(scratch, Operand(character, seed));
  6051
+    __ shl(scratch, 10);
  6052
+    __ lea(hash, Operand(scratch, character, times_1, seed));
  6053
+  }
6040 6054
   // hash ^= hash >> 6;
6041 6055
   __ mov(scratch, hash);
6042 6056
   __ shr(scratch, 6);
22  src/isolate.h
... ...
@@ -1,4 +1,4 @@
1  
-// Copyright 2011 the V8 project authors. All rights reserved.
  1
+// Copyright 2012 the V8 project authors. All rights reserved.
2 2
 // Redistribution and use in source and binary forms, with or without
3 3
 // modification, are permitted provided that the following conditions are
4 4
 // met:
@@ -106,15 +106,21 @@ class Simulator;
106 106
 // of handles to the actual constants.
107 107
 typedef ZoneList<Handle<Object> > ZoneObjectList;
108 108
 
109  
-#define RETURN_IF_SCHEDULED_EXCEPTION(isolate)    \
110  
-  if (isolate->has_scheduled_exception())         \
111  
-      return isolate->PromoteScheduledException()
  109
+#define RETURN_IF_SCHEDULED_EXCEPTION(isolate)            \
  110
+  do {                                                    \
  111
+    Isolate* __isolate__ = (isolate);                     \
  112
+    if (__isolate__->has_scheduled_exception()) {         \
  113
+      return __isolate__->PromoteScheduledException();    \
  114
+    }                                                     \
  115
+  } while (false)
112 116
 
113 117
 #define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value) \
114  
-  if (call.is_null()) {                                    \
115  
-    ASSERT(isolate->has_pending_exception());              \
116  
-    return value;                                          \
117  
-  }
  118
+  do {                                                     \
  119
+    if ((call).is_null()) {                                \
  120
+      ASSERT((isolate)->has_pending_exception());          \
  121
+      return (value);                                      \
  122
+    }                                                      \
  123
+  } while (false)
118 124
 
119 125
 #define RETURN_IF_EMPTY_HANDLE(isolate, call)                       \
120 126
   RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception())
3  src/macros.py
@@ -101,6 +101,9 @@
101 101
 macro IS_ARRAY(arg)             = (%_IsArray(arg));
102 102
 macro IS_FUNCTION(arg)          = (%_IsFunction(arg));
103 103
 macro IS_REGEXP(arg)            = (%_IsRegExp(arg));
  104
+macro IS_SET(arg)               = (%_ClassOf(arg) === 'Set');
  105
+macro IS_MAP(arg)               = (%_ClassOf(arg) === 'Map');
  106
+macro IS_WEAKMAP(arg)           = (%_ClassOf(arg) === 'WeakMap');
104 107
 macro IS_DATE(arg)              = (%_ClassOf(arg) === 'Date');
105 108
 macro IS_NUMBER_WRAPPER(arg)    = (%_ClassOf(arg) === 'Number');
106 109
 macro IS_STRING_WRAPPER(arg)    = (%_ClassOf(arg) === 'String');
34  src/math.js
... ...
@@ -1,4 +1,4 @@
1  
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
  1
+// Copyright 2012 the V8 project authors. All rights reserved.
2 2
 // Redistribution and use in source and binary forms, with or without
3 3
 // modification, are permitted provided that the following conditions are
4 4
 // met:
@@ -119,6 +119,19 @@ function MathLog(x) {
119 119
 // ECMA 262 - 15.8.2.11
120 120
 function MathMax(arg1, arg2) {  // length == 2
121 121
   var length = %_ArgumentsLength();
  122
+  if (length == 2) {
  123
+    if (!IS_NUMBER(arg1)) arg1 = NonNumberToNumber(arg1);
  124
+    if (!IS_NUMBER(arg2)) arg2 = NonNumberToNumber(arg2);
  125
+    if (arg2 > arg1) return arg2;
  126
+    if (arg1 > arg2) return arg1;
  127
+    if (arg1 == arg2) {
  128
+      // Make sure -0 is considered less than +0.  -0 is never a Smi, +0 can be
  129
+      // a Smi or a heap number.
  130
+      return (arg1 == 0 && !%_IsSmi(arg1) && 1 / arg1 < 0) ? arg2 : arg1;
  131
+    }
  132
+    // All comparisons failed, one of the arguments must be NaN.
  133
+    return 0/0;  // Compiler constant-folds this to NaN.
  134
+  }
122 135
   if (length == 0) {
123 136
     return -1/0;  // Compiler constant-folds this to -Infinity.
124 137
   }
@@ -131,7 +144,7 @@ function MathMax(arg1, arg2) {  // length == 2
131 144
     if (NUMBER_IS_NAN(n)) return n;
132 145
     // Make sure +0 is considered greater than -0.  -0 is never a Smi, +0 can be
133 146
     // a Smi or heap number.
134  
-    if (n > r || (r === 0 && n === 0 && !%_IsSmi(r) && 1 / r < 0)) r = n;
  147
+    if (n > r || (r == 0 && n == 0 && !%_IsSmi(r) && 1 / r < 0)) r = n;
135 148
   }
136 149
   return r;
137 150
 }
@@ -139,6 +152,19 @@ function MathMax(arg1, arg2) {  // length == 2
139 152
 // ECMA 262 - 15.8.2.12
140 153
 function MathMin(arg1, arg2) {  // length == 2
141 154
   var length = %_ArgumentsLength();
  155
+  if (length == 2) {
  156
+    if (!IS_NUMBER(arg1)) arg1 = NonNumberToNumber(arg1);
  157
+    if (!IS_NUMBER(arg2)) arg2 = NonNumberToNumber(arg2);
  158
+    if (arg2 > arg1) return arg1;
  159
+    if (arg1 > arg2) return arg2;
  160
+    if (arg1 == arg2) {
  161
+      // Make sure -0 is considered less than +0.  -0 is never a Smi, +0 can be
  162
+      // a Smi or a heap number.
  163
+      return (arg1 == 0 && !%_IsSmi(arg1) && 1 / arg1 < 0) ? arg1 : arg2;
  164
+    }
  165
+    // All comparisons failed, one of the arguments must be NaN.
  166
+    return 0/0;  // Compiler constant-folds this to NaN.
  167
+  }
142 168
   if (length == 0) {
143 169
     return 1/0;  // Compiler constant-folds this to Infinity.
144 170
   }
@@ -149,9 +175,9 @@ function MathMin(arg1, arg2) {  // length == 2
149 175
     var n = %_Arguments(i);
150 176
     if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
151 177
     if (NUMBER_IS_NAN(n)) return n;
152  
-    // Make sure -0 is considered less than +0.  -0 is never a Smi, +0 can b a
  178
+    // Make sure -0 is considered less than +0.  -0 is never a Smi, +0 can be a
153 179
     // Smi or a heap number.
154  
-    if (n < r || (r === 0 && n === 0 && !%_IsSmi(n) && 1 / n < 0)) r = n;
  180
+    if (n < r || (r == 0 && n == 0 && !%_IsSmi(n) && 1 / n < 0)) r = n;
155 181
   }
156 182
   return r;
157 183
 }
69  src/mips/builtins-mips.cc
... ...
@@ -1,4 +1,4 @@
1  
-// Copyright 2011 the V8 project authors. All rights reserved.
  1
+// Copyright 2012 the V8 project authors. All rights reserved.
2 2
 // Redistribution and use in source and binary forms, with or without
3 3
 // modification, are permitted provided that the following conditions are
4 4
 // met:
@@ -74,17 +74,33 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
74 74
 }
75 75
 
76 76
 
  77
+// Load the built-in InternalArray function from the current context.
  78
+static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
  79
+                                              Register result) {
  80
+  // Load the global context.
  81
+
  82
+  __ lw(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
  83
+  __ lw(result,
  84
+        FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
  85
+  // Load the InternalArray function from the global context.
  86
+  __ lw(result,
  87
+         MemOperand(result,
  88
+                    Context::SlotOffset(
  89
+                        Context::INTERNAL_ARRAY_FUNCTION_INDEX)));
  90
+}
  91
+
  92
+
77 93
 // Load the built-in Array function from the current context.
78 94
 static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
79 95
   // Load the global context.
80 96
 
81 97
   __ lw(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
82 98
   __ lw(result,
83  
-         FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
  99
+        FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
84 100
   // Load the Array function from the global context.
85 101
   __ lw(result,
86  
-         MemOperand(result,
87  
-                    Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
  102
+        MemOperand(result,
  103
+                   Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
88 104
 }
89 105
 
90 106
 
@@ -308,7 +324,8 @@ static void AllocateJSArray(MacroAssembler* masm,
308 324
 static void ArrayNativeCode(MacroAssembler* masm,
309 325
                             Label* call_generic_code) {
310 326
   Counters* counters = masm->isolate()->counters();
311  
-  Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array;
  327
+  Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array,
  328
+      has_non_smi_element;
312 329
 
313 330
   // Check for array construction with zero arguments or one.
314 331
   __ Branch(&argc_one_or_more, ne, a0, Operand(zero_reg));
@@ -406,7 +423,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
406 423
   __ lw(a2, MemOperand(t3));
407 424
   __ Addu(t3, t3, kPointerSize);
408 425
   if (FLAG_smi_only_arrays) {
409  
-    __ JumpIfNotSmi(a2, call_generic_code);
  426
+    __ JumpIfNotSmi(a2, &has_non_smi_element);
410 427
   }
411 428
   __ Addu(t1, t1, -kPointerSize);
412 429
   __ sw(a2, MemOperand(t1));
@@ -422,6 +439,46 @@ static void ArrayNativeCode(MacroAssembler* masm,
422 439
   __ Addu(sp, sp, Operand(kPointerSize));
423 440
   __ mov(v0, a3);
424 441
   __ Ret();
  442
+
  443
+  __ bind(&has_non_smi_element);
  444
+  __ UndoAllocationInNewSpace(a3, t0);
  445
+  __ b(call_generic_code);
  446
+}
  447
+
  448
+
  449
+void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
  450
+  // ----------- S t a t e -------------
  451
+  //  -- a0     : number of arguments
  452
+  //  -- ra     : return address
  453
+  //  -- sp[...]: constructor arguments
  454
+  // -----------------------------------
  455
+  Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
  456
+
  457
+  // Get the InternalArray function.
  458
+  GenerateLoadInternalArrayFunction(masm, a1);
  459
+
  460
+  if (FLAG_debug_code) {
  461
+    // Initial map for the builtin InternalArray functions should be maps.
  462
+    __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
  463
+    __ And(t0, a2, Operand(kSmiTagMask));
  464
+    __ Assert(ne, "Unexpected initial map for InternalArray function",
  465
+              t0, Operand(zero_reg));
  466
+    __ GetObjectType(a2, a3, t0);
  467
+    __ Assert(eq, "Unexpected initial map for InternalArray function",
  468
+              t0, Operand(MAP_TYPE));
  469
+  }
  470
+
  471
+  // Run the native code for the InternalArray function called as a normal
  472
+  // function.
  473
+  ArrayNativeCode(masm, &generic_array_code);
  474
+
  475
+  // Jump to the generic array code if the specialized code cannot handle the
  476
+  // construction.
  477
+  __ bind(&generic_array_code);
  478
+
  479
+  Handle<Code> array_code =
  480
+      masm->isolate()->builtins()->InternalArrayCodeGeneric();
  481
+  __ Jump(array_code, RelocInfo::CODE_TARGET);
425 482
 }
426 483
 
427 484
 
16  src/mips/code-stubs-mips.cc
@@ -5924,11 +5924,15 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
5924 5924
 
5925 5925
 
5926 5926
 void StringHelper::GenerateHashInit(MacroAssembler* masm,
5927  
-                                      Register hash,
5928  
-                                      Register character) {
5929  
-  // hash = character + (character << 10);
5930  
-  __ sll(hash, character, 10);
  5927
+                                    Register hash,
  5928
+                                    Register character) {
  5929
+  // hash = seed + character + ((seed + character) << 10);
  5930
+  __ LoadRoot(hash, Heap::kStringHashSeedRootIndex);
  5931
+  // Untag smi seed and add the character.
  5932
+  __ SmiUntag(hash);
5931 5933
   __ addu(hash, hash, character);
  5934
+  __ sll(at, hash, 10);
  5935
+  __ addu(hash, hash, at);
5932 5936
   // hash ^= hash >> 6;
5933 5937
   __ srl(at, hash, 6);
5934 5938
   __ xor_(hash, hash, at);
@@ -5936,8 +5940,8 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
5936 5940
 
5937 5941
 
5938 5942
 void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm,
5939  
-                                              Register hash,
5940  
-                                              Register character) {
  5943
+                                            Register hash,
  5944
+                                            Register character) {
5941 5945
   // hash += character;
5942 5946
   __ addu(hash, hash, character);
5943 5947
   // hash += hash << 10;
12  src/mips/lithium-codegen-mips.cc
@@ -353,6 +353,18 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
353 353
 }
354 354
 
355 355
 
  356
+Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
  357
+  Handle<Object> literal = chunk_->LookupLiteral(op);
  358
+  ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
  359
+  return literal;
  360
+}
  361
+
  362
+
  363
+bool LCodeGen::IsInteger32(LConstantOperand* op) const {
  364
+  return chunk_->LookupLiteralRepresentation(op).IsInteger32();
  365
+}
  366
+
  367
+
356 368
 int LCodeGen::ToInteger32(LConstantOperand* op) const {
357 369
   Handle<Object> value = chunk_->LookupLiteral(op);
358 370
   ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32());
3  src/mips/lithium-codegen-mips.h
@@ -93,6 +93,9 @@ class LCodeGen BASE_EMBEDDED {
93 93
   // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
94 94
   MemOperand ToHighMemOperand(LOperand* op) const;
95 95
 
  96
+  bool IsInteger32(LConstantOperand* op) const;
  97
+  Handle<Object> ToHandle(LConstantOperand* op) const;
  98
+
96 99
   // Try to generate code for the entire chunk, but it may fail if the
97 100
   // chunk contains constructs we cannot handle. Returns true if the
98 101
   // code generation attempt succeeded.
18  src/mips/lithium-gap-resolver-mips.cc
@@ -252,14 +252,24 @@ void LGapResolver::EmitMove(int index) {
252 252
     }
253 253
 
254 254
   } else if (source->IsConstantOperand()) {
255  
-    Operand source_operand = cgen_->ToOperand(source);
  255
+    LConstantOperand* constant_source = LConstantOperand::cast(source);
256 256
     if (destination->IsRegister()) {
257  
-      __ li(cgen_->ToRegister(destination), source_operand);
  257
+      Register dst = cgen_->ToRegister(destination);
  258
+      if (cgen_->IsInteger32(constant_source)) {
  259
+        __ li(dst, Operand(cgen_->ToInteger32(constant_source)));
  260
+      } else {
  261
+        __ LoadObject(dst, cgen_->ToHandle(constant_source));
  262
+      }
258 263
     } else {
259 264
       ASSERT(destination->IsStackSlot());
260 265
       ASSERT(!in_cycle_);  // Constant moves happen after all cycles are gone.
261  
-      MemOperand destination_operand = cgen_->ToMemOperand(destination);
262  
-      __ li(kSavedValueRegister, source_operand);
  266
+      if (cgen_->IsInteger32(constant_source)) {
  267
+        __ li(kSavedValueRegister,
  268
+              Operand(cgen_->ToInteger32(constant_source)));
  269
+      } else {
  270
+        __ LoadObject(kSavedValueRegister,
  271
+                      cgen_->ToHandle(constant_source));
  272
+      }
263 273
       __ sw(kSavedValueRegister, cgen_->ToMemOperand(destination));
264 274
     }
265 275
 
8  src/mips/macro-assembler-mips.h
@@ -264,6 +264,14 @@ class MacroAssembler: public Assembler {
264 264
 
265 265
   void LoadHeapObject(Register dst, Handle<HeapObject> object);
266 266
 
  267
+  void LoadObject(Register result, Handle<Object> object) {
  268
+    if (object->IsHeapObject()) {
  269
+      LoadHeapObject(result, Handle<HeapObject>::cast(object));
  270
+    } else {
  271
+      li(result, object);
  272
+    }
  273
+  }
  274
+
267 275
   // ---------------------------------------------------------------------------
268 276
   // GC Support
269 277
 
19  src/objects-inl.h
@@ -2062,8 +2062,9 @@ int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2062 2062
   // EnsureCapacity will guarantee the hash table is never full.
2063 2063
   while (true) {
2064 2064
     Object* element = KeyAt(entry);
2065  
-    if (element == isolate->heap()->undefined_value()) break;  // Empty entry.
2066  
-    if (element != isolate->heap()->the_hole_value() &&
  2065
+    // Empty entry.
  2066
+    if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
  2067
+    if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
2067 2068
         Shape::IsMatch(key, element)) return entry;
2068 2069
     entry = NextProbe(entry, count++, capacity);
2069 2070
   }
@@ -4320,13 +4321,15 @@ uint32_t String::Hash() {
4320 4321
 }
4321 4322
 
4322 4323
 
4323  
-StringHasher::StringHasher(int length)
  4324
+StringHasher::StringHasher(int length, uint32_t seed)
4324 4325
   : length_(length),
4325  
-    raw_running_hash_(0),
  4326
+    raw_running_hash_(seed),
4326 4327
     array_index_(0),
4327 4328
     is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4328 4329
     is_first_char_(true),
4329  
-    is_valid_(true) { }
  4330
+    is_valid_(true) {
  4331
+  ASSERT(FLAG_randomize_string_hashes || raw_running_hash_ == 0);
  4332
+}
4330 4333
 
4331 4334
 
4332 4335
 bool StringHasher::has_trivial_hash() {
@@ -4378,7 +4381,7 @@ uint32_t StringHasher::GetHash() {
4378 4381
   result += (result << 3);
4379 4382
   result ^= (result >> 11);
4380 4383
   result += (result << 15);
4381  
-  if (result == 0) {
  4384
+  if ((result & String::kHashBitMask) == 0) {
4382 4385
     result = 27;
4383 4386
   }
4384 4387
   return result;
@@ -4386,8 +4389,8 @@ uint32_t StringHasher::GetHash() {
4386 4389
 
4387 4390
 
4388 4391
 template <typename schar>
4389  
-uint32_t HashSequentialString(const schar* chars, int length) {
4390  
-  StringHasher hasher(length);
  4392
+uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
  4393
+  StringHasher hasher(length, seed);
4391 4394
   if (!hasher.has_trivial_hash()) {
4392 4395
     int i;
4393 4396
     for (i = 0; hasher.is_array_index() && (i < length); i++) {
82  src/objects.cc
@@ -6682,6 +6682,20 @@ bool String::SlowEquals(String* other) {
6682 6682
   // Fast check: if hash code is computed for both strings
6683 6683
   // a fast negative check can be performed.
6684 6684
   if (HasHashCode() && other->HasHashCode()) {
  6685
+#ifdef DEBUG
  6686
+    if (FLAG_enable_slow_asserts) {
  6687
+      if (Hash() != other->Hash()) {
  6688
+        bool found_difference = false;
  6689
+        for (int i = 0; i < len; i++) {
  6690
+          if (Get(i) != other->Get(i)) {
  6691
+            found_difference = true;
  6692
+            break;
  6693
+          }
  6694
+        }
  6695
+        ASSERT(found_difference);
  6696
+      }
  6697
+    }
  6698
+#endif
6685 6699
     if (Hash() != other->Hash()) return false;
6686 6700
   }
6687 6701
 
@@ -6817,12 +6831,16 @@ uint32_t String::ComputeAndSetHash() {
6817 6831
   // Compute the hash code.
6818 6832
   uint32_t field = 0;
6819 6833
   if (StringShape(this).IsSequentialAscii()) {
6820  
-    field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), len);
  6834
+    field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(),
  6835
+                                 len,
  6836
+                                 GetHeap()->StringHashSeed());
6821 6837
   } else if (StringShape(this).IsSequentialTwoByte()) {
6822  
-    field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), len);
  6838
+    field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(),
  6839
+                                 len,
  6840
+                                 GetHeap()->StringHashSeed());
6823 6841
   } else {
6824 6842
     StringInputBuffer buffer(this);
6825  
-    field = ComputeHashField(&buffer, len);
  6843
+    field = ComputeHashField(&buffer, len, GetHeap()->StringHashSeed());
6826 6844
   }
6827 6845
 
6828 6846
   // Store the hash code in the object.
@@ -6913,8 +6931,9 @@ uint32_t StringHasher::GetHashField() {
6913 6931
 
6914 6932
 
6915 6933
 uint32_t String::ComputeHashField(unibrow::CharacterStream* buffer,
6916  
-                                  int length) {
6917  
-  StringHasher hasher(length);
  6934
+                                  int length,
  6935
+                                  uint32_t seed) {
  6936
+  StringHasher hasher(length, seed);
6918 6937
 
6919 6938
   // Very long strings have a trivial hash that doesn't inspect the
6920 6939
   // string contents.
@@ -10456,8 +10475,8 @@ class RegExpKey : public HashTableKey {
10456 10475
 // Utf8SymbolKey carries a vector of chars as key.
10457 10476
 class Utf8SymbolKey : public HashTableKey {
10458 10477
  public:
10459  
-  explicit Utf8SymbolKey(Vector<const char> string)
10460  
-      : string_(string), hash_field_(0) { }
  10478
+  explicit Utf8SymbolKey(Vector<const char> string, uint32_t seed)
  10479
+      : string_(string), hash_field_(0), seed_(seed) { }
10461 10480
 
10462 10481
   bool IsMatch(Object* string) {
10463 10482
     return String::cast(string)->IsEqualTo(string_);
@@ -10468,7 +10487,7 @@ class Utf8SymbolKey : public HashTableKey {
10468 10487
     unibrow::Utf8InputBuffer<> buffer(string_.start(),
10469 10488
                                       static_cast<unsigned>(string_.length()));
10470 10489
     chars_ = buffer.Length();
10471  
-    hash_field_ = String::ComputeHashField(&buffer, chars_);
  10490
+    hash_field_ = String::ComputeHashField(&buffer, chars_, seed_);
10472 10491
     uint32_t result = hash_field_ >> String::kHashShift;
10473 10492
     ASSERT(result != 0);  // Ensure that the hash value of 0 is never computed.
10474 10493
     return result;
@@ -10487,17 +10506,18 @@ class Utf8SymbolKey : public HashTableKey {
10487 10506
   Vector<const char> string_;
10488 10507
   uint32_t hash_field_;
10489 10508
   int chars_;  // Caches the number of characters when computing the hash code.
  10509
+  uint32_t seed_;
10490 10510
 };
10491 10511
 
10492 10512
 
10493 10513
 template <typename Char>
10494 10514
 class SequentialSymbolKey : public HashTableKey {
10495 10515
  public:
10496  
-  explicit SequentialSymbolKey(Vector<const Char> string)
10497  
-      : string_(string), hash_field_(0) { }
  10516
+  explicit SequentialSymbolKey(Vector<const Char> string, uint32_t seed)
  10517
+      : string_(string), hash_field_(0), seed_(seed) { }
10498 10518
 
10499 10519
   uint32_t Hash() {
10500  
-    StringHasher hasher(string_.length());
  10520
+    StringHasher hasher(string_.length(), seed_);
10501 10521
 
10502 10522
     // Very long strings have a trivial hash that doesn't inspect the
10503 10523
     // string contents.
@@ -10533,14 +10553,15 @@ class SequentialSymbolKey : public HashTableKey {
10533 10553
 
10534 10554
   Vector<const Char> string_;
10535 10555
   uint32_t hash_field_;
  10556
+  uint32_t seed_;
10536 10557
 };
10537 10558