Version 3.6.0

Fixed a bug when optimizing named function expression (issue 1647).

Fixed a bug when optimizing f.call.apply (issue 1650).

Made arguments and caller always be null on native functions (issues 1548 and 1643).

Fixed issue 1648 (cross-compiling x64 targeting ia32).

Fixed issue 371 (d8 printing of strings containing \0).

Fixed order of evaluation in arguments to parseInt (issue 1649).

Fixed a problem with large heap snapshots in Chrome DevTools (issue 1658, chromium issue 89268).

Upped default maximum heap size from 512M to 700M.




git-svn-id: http://v8.googlecode.com/svn/trunk@9132 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 02d0ebb..9dd6f88 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2011-09-05: Version 3.6.0
+
+	Fixed a bug when optimizing named function expression (issue 1647).
+
+	Fixed a bug when optimizing f.call.apply (issue 1650).
+
+	Made arguments and caller always be null on native functions
+	(issues 1548 and 1643).
+
+	Fixed issue 1648 (cross-compiling x64 targeting ia32).
+
+	Fixed issue 371 (d8 printing of strings containing \0).
+
+	Fixed order of evaluation in arguments to parseInt (issue 1649).
+
+	Fixed a problem with large heap snapshots in Chrome DevTools
+	(issue 1658, chromium issue 89268).
+
+	Upped default maximum heap size from 512M to 700M.
+
+
 2011-08-31: Version 3.5.10
 
         Added dependency of v8_base on WinSocket2 Windows library in
diff --git a/Makefile b/Makefile
index 3008779..618bbef 100644
--- a/Makefile
+++ b/Makefile
@@ -98,8 +98,9 @@
 # File where previously used GYPFLAGS are stored.
 ENVFILE = $(OUTDIR)/environment
 
-.PHONY: all clean $(ENVFILE).new \
-        $(ARCHES) $(MODES) $(BUILDS) $(addsuffix .clean,$(ARCHES))
+.PHONY: all check clean $(ENVFILE).new \
+        $(ARCHES) $(MODES) $(BUILDS) $(CHECKS) $(addsuffix .clean,$(ARCHES)) \
+        $(addsuffix .check,$(MODES)) $(addsuffix .check,$(ARCHES))
 
 # Target definitions. "all" is the default.
 all: $(MODES)
diff --git a/benchmarks/crypto.js b/benchmarks/crypto.js
index ffa69b5..531ad45 100644
--- a/benchmarks/crypto.js
+++ b/benchmarks/crypto.js
@@ -1406,7 +1406,7 @@
 
 // Mix in the current time (w/milliseconds) into the pool
 function rng_seed_time() {
-  // Use pre-computed date to avoid making the benchmark 
+  // Use pre-computed date to avoid making the benchmark
   // results dependent on the current date.
   rng_seed_int(1122926989487);
 }
diff --git a/benchmarks/earley-boyer.js b/benchmarks/earley-boyer.js
index 1be480e..b2328d6 100644
--- a/benchmarks/earley-boyer.js
+++ b/benchmarks/earley-boyer.js
@@ -134,7 +134,7 @@
 /*** META ((export #t)) */
 function sc_any2String(o) {
     return jsstring2string(sc_toDisplayString(o));
-}    
+}
 
 /*** META ((export #t)
            (peephole (infix 2 2 "==="))
@@ -923,7 +923,7 @@
     tmp.cdr = l2;
     return l1;
 }
-    
+
 /*** META ((export #t)) */
 function sc_appendBang() {
     var res = null;
@@ -1163,7 +1163,7 @@
     "us": "\037",
     "sp": "\040",
     "del": "\177"};
-    
+
 sc_Char.prototype.toString = function() {
     return this.val;
 };
@@ -1533,7 +1533,7 @@
     }
     return l1_orig;
 }
-     
+
 /*** META ((export #t)) */
 function sc_forEach(proc, l1) {
     if (l1 === undefined)
@@ -1871,7 +1871,7 @@
 	evalStr += ", arguments[" + i + "]";
     evalStr +=")";
     return eval(evalStr);
-}    
+}
 
 // ======================== RegExp ====================
 /*** META ((export #t)) */
@@ -1883,9 +1883,9 @@
 function sc_pregexpMatch(re, s) {
     var reg = (re instanceof RegExp) ? re : sc_pregexp(re);
     var tmp = reg.exec(sc_string2jsstring(s));
-    
+
     if (tmp == null) return false;
-    
+
     var res = null;
     for (var i = tmp.length-1; i >= 0; i--) {
 	if (tmp[i] !== null) {
@@ -1896,7 +1896,7 @@
     }
     return res;
 }
-   
+
 /*** META ((export #t)) */
 function sc_pregexpReplace(re, s1, s2) {
    var reg;
@@ -1914,7 +1914,7 @@
 
    return jss1.replace(reg, jss2);
 }
-   
+
 /*** META ((export pregexp-replace*)) */
 function sc_pregexpReplaceAll(re, s1, s2) {
    var reg;
@@ -1945,7 +1945,7 @@
 
    return sc_vector2list(tmp);
 }
-   
+
 
 /* =========================================================================== */
 /* Other library stuff */
@@ -2136,7 +2136,7 @@
 sc_ErrorInputPort.prototype.isCharReady = function() {
     return false;
 };
-    
+
 
 /* .............. String port ..........................*/
 
@@ -2200,7 +2200,7 @@
 };
 sc_Tokenizer.prototype.nextToken = function() {
     var port = this.port;
-    
+
     function isNumberChar(c) {
 	return (c >= "0" && c <= "9");
     };
@@ -2280,7 +2280,7 @@
 	else
 	    return new sc_Token(12/*NUMBER*/, res - 0);
     };
-    
+
     function skipWhitespaceAndComments() {
 	var done = false;
 	while (!done) {
@@ -2299,7 +2299,7 @@
 	    }
 	}
     };
-    
+
     function readDot() {
 	if (isWhitespace(port.peekChar()))
 	    return new sc_Token(10/*DOT*/);
@@ -2429,7 +2429,7 @@
 
 	while (true) {
 	    var token = tokenizer.peekToken();
-	    
+
 	    switch (token.type) {
 	    case 2/*CLOSE_PAR*/:
 	    case 4/*CLOSE_BRACE*/:
@@ -2491,7 +2491,7 @@
 	else
 	    throw "bad reference: " + nb;
     };
-    
+
     var tokenizer = this.tokenizer;
 
     var token = tokenizer.readToken();
@@ -2499,7 +2499,7 @@
     // handle error
     if (token.type === 13/*ERROR*/)
 	throw token.val;
-    
+
     switch (token.type) {
     case 1/*OPEN_PAR*/:
     case 3/*OPEN_BRACE*/:
@@ -2550,7 +2550,7 @@
 	port = SC_DEFAULT_IN; // THREAD: shared var...
     var t = port.peekChar();
     return t === SC_EOF_OBJECT? t: new sc_Char(t);
-}    
+}
 /*** META ((export #t)
            (type bool))
 */
@@ -2722,7 +2722,7 @@
 function sc_getOutputString(sp) {
     return sc_jsstring2string(sp.res);
 }
-    
+
 
 function sc_ErrorOutputPort() {
 }
@@ -2852,7 +2852,7 @@
 	p = SC_DEFAULT_OUT;
     p.appendJSString("\n");
 }
-    
+
 /* ------------------ write-char ---------------------------------------------------*/
 
 /*** META ((export #t)) */
@@ -2927,7 +2927,7 @@
     }
 
     var res = "";
-    
+
     if (this[symb] !== undefined) { // implies > 0
 	this[symb + "use"] = true;
 	if (inList)
@@ -2939,10 +2939,10 @@
 
     if (!inList)
 	res += "(";
-    
+
     // print car
     res += sc_genToWriteCircleString(this.car, symb);
-    
+
     if (sc_isPair(this.cdr)) {
 	res += " " + this.cdr.sc_toWriteCircleString(symb, true);
     } else if (this.cdr !== null) {
@@ -3072,7 +3072,7 @@
 	       p.appendJSString(arguments[j].toString(2));
 	       i += 2; j++;
 	       break;
-	       
+
 	    case 37:
 	    case 110:
 	       // %, n
@@ -3186,7 +3186,7 @@
 function sc_number2symbol(x, radix) {
     return sc_SYMBOL_PREFIX + sc_number2jsstring(x, radix);
 }
-    
+
 /*** META ((export number->string integer->string)) */
 var sc_number2string = sc_number2jsstring;
 
diff --git a/benchmarks/regexp.js b/benchmarks/regexp.js
index 71b9e63..9c83142 100644
--- a/benchmarks/regexp.js
+++ b/benchmarks/regexp.js
@@ -33,7 +33,7 @@
 // the popularity of the pages where it occurs and the number of times
 // it is executed while loading each page.  Furthermore the literal
 // letters in the data are encoded using ROT13 in a way that does not
-// affect how the regexps match their input.  Finally the strings are 
+// affect how the regexps match their input.  Finally the strings are
 // scrambled to exercise the regexp engine on different input strings.
 
 
@@ -47,7 +47,7 @@
   regExpBenchmark = new RegExpBenchmark();
   RegExpRun(); // run once to get system initialized
 }
-  
+
 function RegExpRun() {
   regExpBenchmark.run();
 }
@@ -1759,6 +1759,6 @@
       runBlock11();
     }
   }
-  
+
   this.run = run;
 }
diff --git a/build/all.gyp b/build/all.gyp
index 9c0f05c..4b2fe52 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Copyright 2011 the V8 project authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
@@ -11,13 +11,7 @@
         '../preparser/preparser.gyp:*',
         '../samples/samples.gyp:*',
         '../src/d8.gyp:d8',
-      ],
-      'conditions': [
-        [ 'component!="shared_library"', {
-          'dependencies': [
-            '../test/cctest/cctest.gyp:*',
-          ],
-        }]
+        '../test/cctest/cctest.gyp:*',
       ],
     }
   ]
diff --git a/build/common.gypi b/build/common.gypi
index 834516f..9b32608 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -173,6 +173,14 @@
           },
         },
       }],
+      ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
+        'conditions': [
+          [ 'target_arch=="ia32"', {
+            'cflags': [ '-m32' ],
+            'ldflags': [ '-m32' ],
+          }],
+        ],
+      }],
     ],
     'configurations': {
       'Debug': {
diff --git a/build/standalone.gypi b/build/standalone.gypi
index 81909f1..cb5e133 100644
--- a/build/standalone.gypi
+++ b/build/standalone.gypi
@@ -79,10 +79,6 @@
                     '-fno-exceptions', '-pedantic' ],
         'ldflags': [ '-pthread', ],
         'conditions': [
-          [ 'target_arch=="ia32"', {
-            'cflags': [ '-m32' ],
-            'ldflags': [ '-m32' ],
-          }],
           [ 'OS=="linux"', {
             'cflags': [ '-ansi' ],
           }],
diff --git a/include/v8.h b/include/v8.h
index 5a78160..80193c4 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1656,7 +1656,7 @@
   V8EXPORT bool IsCallable();
 
   /**
-   * Call an Object as a function if a callback is set by the 
+   * Call an Object as a function if a callback is set by the
    * ObjectTemplate::SetCallAsFunctionHandler method.
    */
   V8EXPORT Local<Value> CallAsFunction(Handle<Object> recv,
@@ -3562,7 +3562,7 @@
  * // V8 Now no longer locked.
  * \endcode
  *
- * 
+ *
  */
 class V8EXPORT Unlocker {
  public:
diff --git a/samples/shell.cc b/samples/shell.cc
index 8ed9d03..b40eca2 100644
--- a/samples/shell.cc
+++ b/samples/shell.cc
@@ -250,16 +250,14 @@
   static const int kBufferSize = 256;
   // Enter the execution environment before evaluating any code.
   v8::Context::Scope context_scope(context);
+  v8::Local<v8::String> name(v8::String::New("(shell)"));
   while (true) {
     char buffer[kBufferSize];
     printf("> ");
     char* str = fgets(buffer, kBufferSize, stdin);
     if (str == NULL) break;
     v8::HandleScope handle_scope;
-    ExecuteString(v8::String::New(str),
-                  v8::String::New("(shell)"),
-                  true,
-                  true);
+    ExecuteString(v8::String::New(str), name, true, true);
   }
   printf("\n");
 }
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 09d2c17..c310da8 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -4487,7 +4487,7 @@
   // frame. Therefore we have to use fp, which points exactly to two pointer
   // sizes below the previous sp. (Because creating a new stack frame pushes
   // the previous fp onto the stack and moves up sp by 2 * kPointerSize.)
-  __ ldr(r0, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
+  __ ldr(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
   // If slice offset is not 0, load the length from the original sliced string.
   // Argument 4, r3: End of string data
   // Argument 3, r2: Start of string data
@@ -4495,7 +4495,7 @@
   __ add(r9, r8, Operand(r9, LSL, r3));
   __ add(r2, r9, Operand(r1, LSL, r3));
 
-  __ ldr(r8, FieldMemOperand(r0, String::kLengthOffset));
+  __ ldr(r8, FieldMemOperand(subject, String::kLengthOffset));
   __ mov(r8, Operand(r8, ASR, kSmiTagSize));
   __ add(r3, r9, Operand(r8, LSL, r3));
 
@@ -4503,7 +4503,7 @@
   // Already there
 
   // Argument 1 (r0): Subject string.
-  // Already there
+  __ mov(r0, subject);
 
   // Locate the code entry and call it.
   __ add(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag));
@@ -4520,12 +4520,12 @@
   // Check the result.
   Label success;
 
-  __ cmp(subject, Operand(NativeRegExpMacroAssembler::SUCCESS));
+  __ cmp(r0, Operand(NativeRegExpMacroAssembler::SUCCESS));
   __ b(eq, &success);
   Label failure;
-  __ cmp(subject, Operand(NativeRegExpMacroAssembler::FAILURE));
+  __ cmp(r0, Operand(NativeRegExpMacroAssembler::FAILURE));
   __ b(eq, &failure);
-  __ cmp(subject, Operand(NativeRegExpMacroAssembler::EXCEPTION));
+  __ cmp(r0, Operand(NativeRegExpMacroAssembler::EXCEPTION));
   // If not exception it can only be retry. Handle that in the runtime system.
   __ b(ne, &runtime);
   // Result must now be exception. If there is no pending exception already a
@@ -4537,18 +4537,18 @@
   __ mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address,
                                        isolate)));
   __ ldr(r0, MemOperand(r2, 0));
-  __ cmp(subject, r1);
+  __ cmp(r0, r1);
   __ b(eq, &runtime);
 
   __ str(r1, MemOperand(r2, 0));  // Clear pending exception.
 
   // Check if the exception is a termination. If so, throw as uncatchable.
-  __ LoadRoot(ip, Heap::kTerminationExceptionRootIndex);
-  __ cmp(subject, ip);
+  __ CompareRoot(r0, Heap::kTerminationExceptionRootIndex);
+
   Label termination_exception;
   __ b(eq, &termination_exception);
 
-  __ Throw(subject);  // Expects thrown value in r0.
+  __ Throw(r0);  // Expects thrown value in r0.
 
   __ bind(&termination_exception);
   __ ThrowUncatchable(TERMINATION, r0);  // Expects thrown value in r0.
@@ -4894,7 +4894,8 @@
 
   // Check for 1-byte or 2-byte string.
   __ bind(&flat_string);
-  STATIC_ASSERT(kAsciiStringTag != 0);
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
   __ tst(result_, Operand(kStringEncodingMask));
   __ b(ne, &ascii_string);
 
@@ -5468,11 +5469,6 @@
   Register to = r6;
   Register from = r7;
 
-  if (FLAG_string_slices) {
-    __ nop(0);  // Jumping as first instruction would crash the code generation.
-    __ jmp(&runtime);
-  }
-
   __ Ldrd(to, from, MemOperand(sp, kToOffset));
   STATIC_ASSERT(kFromOffset == kToOffset + 4);
   STATIC_ASSERT(kSmiTag == 0);
@@ -5490,64 +5486,79 @@
   __ b(mi, &runtime);  // Fail if from > to.
   // Special handling of sub-strings of length 1 and 2. One character strings
   // are handled in the runtime system (looked up in the single character
-  // cache). Two character strings are looked for in the symbol cache.
+  // cache). Two character strings are looked for in the symbol cache in
+  // generated code.
   __ cmp(r2, Operand(2));
   __ b(lt, &runtime);
 
-  // r2: length
-  // r3: from index (untaged smi)
+  // r2: result string length
+  // r3: from index (untagged smi)
   // r6 (a.k.a. to): to (smi)
   // r7 (a.k.a. from): from offset (smi)
-
   // Make sure first argument is a sequential (or flat) string.
-  __ ldr(r5, MemOperand(sp, kStringOffset));
+  __ ldr(r0, MemOperand(sp, kStringOffset));
   STATIC_ASSERT(kSmiTag == 0);
-  __ JumpIfSmi(r5, &runtime);
-  Condition is_string = masm->IsObjectStringType(r5, r1);
+  __ JumpIfSmi(r0, &runtime);
+  Condition is_string = masm->IsObjectStringType(r0, r1);
   __ b(NegateCondition(is_string), &runtime);
 
+  // Short-cut for the case of trivial substring.
+  Label return_r0;
+  // r0: original string
+  // r2: result string length
+  __ ldr(r4, FieldMemOperand(r0, String::kLengthOffset));
+  __ cmp(r2, Operand(r4, ASR, 1));
+  __ b(eq, &return_r0);
+
+  Label create_slice;
+  if (FLAG_string_slices) {
+    __ cmp(r2, Operand(SlicedString::kMinLength));
+    __ b(ge, &create_slice);
+  }
+
+  // r0: original string
   // r1: instance type
-  // r2: length
+  // r2: result string length
   // r3: from index (untagged smi)
-  // r5: string
   // r6 (a.k.a. to): to (smi)
   // r7 (a.k.a. from): from offset (smi)
   Label seq_string;
   __ and_(r4, r1, Operand(kStringRepresentationMask));
   STATIC_ASSERT(kSeqStringTag < kConsStringTag);
   STATIC_ASSERT(kConsStringTag < kExternalStringTag);
+  STATIC_ASSERT(kConsStringTag < kSlicedStringTag);
   __ cmp(r4, Operand(kConsStringTag));
-  __ b(gt, &runtime);  // External strings go to runtime.
+  __ b(gt, &runtime);  // Slices and external strings go to runtime.
   __ b(lt, &seq_string);  // Sequential strings are handled directly.
 
   // Cons string. Try to recurse (once) on the first substring.
   // (This adds a little more generality than necessary to handle flattened
   // cons strings, but not much).
-  __ ldr(r5, FieldMemOperand(r5, ConsString::kFirstOffset));
-  __ ldr(r4, FieldMemOperand(r5, HeapObject::kMapOffset));
+  __ ldr(r0, FieldMemOperand(r0, ConsString::kFirstOffset));
+  __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
   __ ldrb(r1, FieldMemOperand(r4, Map::kInstanceTypeOffset));
   __ tst(r1, Operand(kStringRepresentationMask));
   STATIC_ASSERT(kSeqStringTag == 0);
-  __ b(ne, &runtime);  // Cons and External strings go to runtime.
+  __ b(ne, &runtime);  // Cons, slices and external strings go to runtime.
 
   // Definitly a sequential string.
   __ bind(&seq_string);
 
-  // r1: instance type.
-  // r2: length
-  // r3: from index (untaged smi)
-  // r5: string
+  // r0: original string
+  // r1: instance type
+  // r2: result string length
+  // r3: from index (untagged smi)
   // r6 (a.k.a. to): to (smi)
   // r7 (a.k.a. from): from offset (smi)
-  __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset));
+  __ ldr(r4, FieldMemOperand(r0, String::kLengthOffset));
   __ cmp(r4, Operand(to));
   __ b(lt, &runtime);  // Fail if to > length.
   to = no_reg;
 
-  // r1: instance type.
-  // r2: result string length.
-  // r3: from index (untaged smi)
-  // r5: string.
+  // r0: original string or left hand side of the original cons string.
+  // r1: instance type
+  // r2: result string length
+  // r3: from index (untagged smi)
   // r7 (a.k.a. from): from offset (smi)
   // Check for flat ASCII string.
   Label non_ascii_flat;
@@ -5561,82 +5572,146 @@
 
   // Sub string of length 2 requested.
   // Get the two characters forming the sub string.
-  __ add(r5, r5, Operand(r3));
-  __ ldrb(r3, FieldMemOperand(r5, SeqAsciiString::kHeaderSize));
-  __ ldrb(r4, FieldMemOperand(r5, SeqAsciiString::kHeaderSize + 1));
+  __ add(r0, r0, Operand(r3));
+  __ ldrb(r3, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
+  __ ldrb(r4, FieldMemOperand(r0, SeqAsciiString::kHeaderSize + 1));
 
   // Try to lookup two character string in symbol table.
   Label make_two_character_string;
   StringHelper::GenerateTwoCharacterSymbolTableProbe(
       masm, r3, r4, r1, r5, r6, r7, r9, &make_two_character_string);
   Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
-  __ add(sp, sp, Operand(3 * kPointerSize));
-  __ Ret();
+  __ jmp(&return_r0);
 
   // r2: result string length.
   // r3: two characters combined into halfword in little endian byte order.
   __ bind(&make_two_character_string);
   __ AllocateAsciiString(r0, r2, r4, r5, r9, &runtime);
   __ strh(r3, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
-  __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
-  __ add(sp, sp, Operand(3 * kPointerSize));
-  __ Ret();
+  __ jmp(&return_r0);
 
   __ bind(&result_longer_than_two);
 
+  // Locate 'from' character of string.
+  __ add(r5, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
+  __ add(r5, r5, Operand(from, ASR, 1));
+
   // Allocate the result.
   __ AllocateAsciiString(r0, r2, r3, r4, r1, &runtime);
 
-  // r0: result string.
-  // r2: result string length.
-  // r5: string.
+  // r0: result string
+  // r2: result string length
+  // r5: first character of substring to copy
   // r7 (a.k.a. from): from offset (smi)
   // Locate first character of result.
   __ add(r1, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
-  // Locate 'from' character of string.
-  __ add(r5, r5, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
-  __ add(r5, r5, Operand(from, ASR, 1));
 
-  // r0: result string.
-  // r1: first character of result string.
-  // r2: result string length.
-  // r5: first character of sub string to copy.
+  // r0: result string
+  // r1: first character of result string
+  // r2: result string length
+  // r5: first character of substring to copy
   STATIC_ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0);
   StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9,
                                            COPY_ASCII | DEST_ALWAYS_ALIGNED);
-  __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
-  __ add(sp, sp, Operand(3 * kPointerSize));
-  __ Ret();
+  __ jmp(&return_r0);
 
   __ bind(&non_ascii_flat);
-  // r2: result string length.
-  // r5: string.
+  // r0: original string
+  // r2: result string length
   // r7 (a.k.a. from): from offset (smi)
   // Check for flat two byte string.
 
+  // Locate 'from' character of string.
+  __ add(r5, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
+  // As "from" is a smi it is 2 times the value which matches the size of a two
+  // byte character.
+  STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
+  __ add(r5, r5, Operand(from));
+
   // Allocate the result.
   __ AllocateTwoByteString(r0, r2, r1, r3, r4, &runtime);
 
-  // r0: result string.
-  // r2: result string length.
-  // r5: string.
+  // r0: result string
+  // r2: result string length
+  // r5: first character of substring to copy
   // Locate first character of result.
   __ add(r1, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
-  // Locate 'from' character of string.
-  __ add(r5, r5, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
-  // As "from" is a smi it is 2 times the value which matches the size of a two
-  // byte character.
-  __ add(r5, r5, Operand(from));
+
   from = no_reg;
 
   // r0: result string.
   // r1: first character of result.
   // r2: result length.
-  // r5: first character of string to copy.
+  // r5: first character of substring to copy.
   STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
   StringHelper::GenerateCopyCharactersLong(
       masm, r1, r5, r2, r3, r4, r6, r7, r9, DEST_ALWAYS_ALIGNED);
+  __ jmp(&return_r0);
+
+  if (FLAG_string_slices) {
+    __ bind(&create_slice);
+    // r0: original string
+    // r1: instance type
+    // r2: length
+    // r3: from index (untagged smi)
+    // r6 (a.k.a. to): to (smi)
+    // r7 (a.k.a. from): from offset (smi)
+    Label allocate_slice, sliced_string, seq_string;
+    STATIC_ASSERT(kSeqStringTag == 0);
+    __ tst(r1, Operand(kStringRepresentationMask));
+    __ b(eq, &seq_string);
+    STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
+    STATIC_ASSERT(kIsIndirectStringMask != 0);
+    __ tst(r1, Operand(kIsIndirectStringMask));
+    // External string.  Jump to runtime.
+    __ b(eq, &runtime);
+
+    __ tst(r1, Operand(kSlicedNotConsMask));
+    __ b(ne, &sliced_string);
+    // Cons string.  Check whether it is flat, then fetch first part.
+    __ ldr(r5, FieldMemOperand(r0, ConsString::kSecondOffset));
+    __ LoadRoot(r9, Heap::kEmptyStringRootIndex);
+    __ cmp(r5, r9);
+    __ b(ne, &runtime);
+    __ ldr(r5, FieldMemOperand(r0, ConsString::kFirstOffset));
+    __ jmp(&allocate_slice);
+
+    __ bind(&sliced_string);
+    // Sliced string.  Fetch parent and correct start index by offset.
+    __ ldr(r5, FieldMemOperand(r0, SlicedString::kOffsetOffset));
+    __ add(r7, r7, r5);
+    __ ldr(r5, FieldMemOperand(r0, SlicedString::kParentOffset));
+    __ jmp(&allocate_slice);
+
+    __ bind(&seq_string);
+    // Sequential string.  Just move string to the right register.
+    __ mov(r5, r0);
+
+    __ bind(&allocate_slice);
+    // r1: instance type of original string
+    // r2: length
+    // r5: underlying subject string
+    // r7 (a.k.a. from): from offset (smi)
+    // Allocate new sliced string.  At this point we do not reload the instance
+    // type including the string encoding because we simply rely on the info
+    // provided by the original string.  It does not matter if the original
+    // string's encoding is wrong because we always have to recheck encoding of
+    // the newly created string's parent anyways due to externalized strings.
+    Label two_byte_slice, set_slice_header;
+    STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+    STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
+    __ tst(r1, Operand(kStringEncodingMask));
+    __ b(eq, &two_byte_slice);
+    __ AllocateAsciiSlicedString(r0, r2, r3, r4, &runtime);
+    __ jmp(&set_slice_header);
+    __ bind(&two_byte_slice);
+    __ AllocateTwoByteSlicedString(r0, r2, r3, r4, &runtime);
+    __ bind(&set_slice_header);
+    __ str(r7, FieldMemOperand(r0, SlicedString::kOffsetOffset));
+    __ str(r5, FieldMemOperand(r0, SlicedString::kParentOffset));
+  }
+
+  __ bind(&return_r0);
   __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
   __ add(sp, sp, Operand(3 * kPointerSize));
   __ Ret();
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 408946e..fc12bd0 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -258,6 +258,7 @@
     scope()->VisitIllegalRedeclaration(this);
 
   } else {
+    PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
     { Comment cmnt(masm_, "[ Declarations");
       // For named function expressions, declare the function name as a
       // constant.
@@ -268,7 +269,7 @@
     }
 
     { Comment cmnt(masm_, "[ Stack check");
-      PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
+      PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
       Label ok;
       __ LoadRoot(ip, Heap::kStackLimitRootIndex);
       __ cmp(sp, Operand(ip));
@@ -687,10 +688,11 @@
 }
 
 
-void FullCodeGenerator::EmitDeclaration(Variable* variable,
+void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
                                         Variable::Mode mode,
                                         FunctionLiteral* function) {
   Comment cmnt(masm_, "[ Declaration");
+  Variable* variable = proxy->var();
   ASSERT(variable != NULL);  // Must have been resolved.
   Slot* slot = variable->AsSlot();
   ASSERT(slot != NULL);
@@ -728,10 +730,12 @@
         // We know that we have written a function, which is not a smi.
         __ mov(r1, Operand(cp));
         __ RecordWrite(r1, Operand(offset), r2, result_register());
+        PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
       } else if (mode == Variable::CONST || mode == Variable::LET) {
         __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
         __ str(ip, ContextOperand(cp, slot->index()));
         // No write barrier since the_hole_value is in old space.
+        PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
       }
       break;
 
@@ -766,18 +770,17 @@
 
 
 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
-  EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
+  EmitDeclaration(decl->proxy(), decl->mode(), decl->fun());
 }
 
 
 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
   // Call the runtime to declare the globals.
   // The context is the first argument.
-  __ mov(r2, Operand(pairs));
-  __ mov(r1, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
-  __ mov(r0, Operand(Smi::FromInt(strict_mode_flag())));
-  __ Push(cp, r2, r1, r0);
-  __ CallRuntime(Runtime::kDeclareGlobals, 4);
+  __ mov(r1, Operand(pairs));
+  __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
+  __ Push(cp, r1, r0);
+  __ CallRuntime(Runtime::kDeclareGlobals, 3);
   // Return value is ignored.
 }
 
@@ -2167,8 +2170,13 @@
   int receiver_offset = 2 + info_->scope()->num_parameters();
   __ ldr(r1, MemOperand(fp, receiver_offset * kPointerSize));
   __ push(r1);
-  // Push the strict mode flag.
-  __ mov(r1, Operand(Smi::FromInt(strict_mode_flag())));
+  // Push the strict mode flag. In harmony mode every eval call
+  // is a strict mode eval call.
+  StrictModeFlag strict_mode = strict_mode_flag();
+  if (FLAG_harmony_block_scoping) {
+    strict_mode = kStrictMode;
+  }
+  __ mov(r1, Operand(Smi::FromInt(strict_mode)));
   __ push(r1);
 
   __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 976576b..03ea929 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -3509,7 +3509,8 @@
 
   // Dispatch on the encoding: ASCII or two-byte.
   Label ascii_string;
-  STATIC_ASSERT(kAsciiStringTag != 0);
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
   __ tst(result, Operand(kStringEncodingMask));
   __ b(ne, &ascii_string);
 
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 88477bb..613a1f6 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -1725,6 +1725,46 @@
 }
 
 
+void MacroAssembler::AllocateTwoByteSlicedString(Register result,
+                                                 Register length,
+                                                 Register scratch1,
+                                                 Register scratch2,
+                                                 Label* gc_required) {
+  AllocateInNewSpace(SlicedString::kSize,
+                     result,
+                     scratch1,
+                     scratch2,
+                     gc_required,
+                     TAG_OBJECT);
+
+  InitializeNewString(result,
+                      length,
+                      Heap::kSlicedStringMapRootIndex,
+                      scratch1,
+                      scratch2);
+}
+
+
+void MacroAssembler::AllocateAsciiSlicedString(Register result,
+                                               Register length,
+                                               Register scratch1,
+                                               Register scratch2,
+                                               Label* gc_required) {
+  AllocateInNewSpace(SlicedString::kSize,
+                     result,
+                     scratch1,
+                     scratch2,
+                     gc_required,
+                     TAG_OBJECT);
+
+  InitializeNewString(result,
+                      length,
+                      Heap::kSlicedAsciiStringMapRootIndex,
+                      scratch1,
+                      scratch2);
+}
+
+
 void MacroAssembler::CompareObjectType(Register object,
                                        Register map,
                                        Register type_reg,
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 9c653ad..9d66359 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -532,6 +532,16 @@
                                Register scratch1,
                                Register scratch2,
                                Label* gc_required);
+  void AllocateTwoByteSlicedString(Register result,
+                                   Register length,
+                                   Register scratch1,
+                                   Register scratch2,
+                                   Label* gc_required);
+  void AllocateAsciiSlicedString(Register result,
+                                 Register length,
+                                 Register scratch1,
+                                 Register scratch2,
+                                 Label* gc_required);
 
   // Allocates a heap number or jumps to the gc_required label if the young
   // space is full and a scavenge is needed. All registers are clobbered also
diff --git a/src/array.js b/src/array.js
index 281c507..32a370f 100644
--- a/src/array.js
+++ b/src/array.js
@@ -1314,12 +1314,13 @@
 
 
 // -------------------------------------------------------------------
-function SetupArray() {
-  // Setup non-enumerable constructor property on the Array.prototype
+function SetUpArray() {
+  %CheckIsBootstrapping();
+  // Set up non-enumerable constructor property on the Array.prototype
   // object.
   %SetProperty($Array.prototype, "constructor", $Array, DONT_ENUM);
 
-  // Setup non-enumerable functions on the Array object.
+  // Set up non-enumerable functions on the Array object.
   InstallFunctions($Array, DONT_ENUM, $Array(
     "isArray", ArrayIsArray
   ));
@@ -1337,7 +1338,7 @@
     return f;
   }
 
-  // Setup non-enumerable functions of the Array.prototype object and
+  // Set up non-enumerable functions of the Array.prototype object and
   // set their names.
   // Manipulate the length of some of the functions to meet
   // expectations set by ECMA-262 or Mozilla.
@@ -1368,19 +1369,13 @@
   %FinishArrayPrototypeSetup($Array.prototype);
 
   // The internal Array prototype doesn't need to be fancy, since it's never
-  // exposed to user code, so no hidden prototypes or DONT_ENUM attributes
-  // are necessary.
-  // The null __proto__ ensures that we never inherit any user created
-  // getters or setters from, e.g., Object.prototype.
-  InternalArray.prototype.__proto__ = null;
-  // Adding only the functions that are actually used, and a toString.
-  InternalArray.prototype.join = getFunction("join", ArrayJoin);
-  InternalArray.prototype.pop = getFunction("pop", ArrayPop);
-  InternalArray.prototype.push = getFunction("push", ArrayPush);
-  InternalArray.prototype.toString = function() {
-    return "Internal Array, length " + this.length;
-  };
+  // exposed to user code.
+  // Adding only the functions that are actually used.
+  SetUpLockedPrototype(InternalArray, $Array(), $Array(
+    "join", getFunction("join", ArrayJoin),
+    "pop", getFunction("pop", ArrayPop),
+    "push", getFunction("push", ArrayPush)
+  ));
 }
 
-
-SetupArray();
+SetUpArray();
diff --git a/src/ast.cc b/src/ast.cc
index 7319abe..4d881d1 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -36,15 +36,6 @@
 namespace v8 {
 namespace internal {
 
-AstSentinels::AstSentinels()
-    : this_proxy_(Isolate::Current(), true),
-      identifier_proxy_(Isolate::Current(), false),
-      valid_left_hand_side_sentinel_(Isolate::Current()),
-      this_property_(Isolate::Current(), &this_proxy_, NULL, 0),
-      call_sentinel_(Isolate::Current(), NULL, NULL, 0) {
-}
-
-
 // ----------------------------------------------------------------------------
 // All the Accept member functions for each syntax tree node type.
 
@@ -101,15 +92,6 @@
 }
 
 
-VariableProxy::VariableProxy(Isolate* isolate, bool is_this)
-    : Expression(isolate),
-      var_(NULL),
-      is_this_(is_this),
-      inside_with_(false),
-      is_trivial_(false) {
-}
-
-
 void VariableProxy::BindTo(Variable* var) {
   ASSERT(var_ == NULL);  // must be bound only once
   ASSERT(var != NULL);  // must bind
@@ -487,12 +469,6 @@
 }
 
 
-bool ValidLeftHandSideSentinel::IsInlineable() const {
-  UNREACHABLE();
-  return false;
-}
-
-
 bool ForStatement::IsInlineable() const {
   return (init() == NULL || init()->IsInlineable())
       && (cond() == NULL || cond()->IsInlineable())
diff --git a/src/ast.h b/src/ast.h
index 74182d5..3d53b5f 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -134,6 +134,10 @@
 
   static const int kNoNumber = -1;
   static const int kFunctionEntryId = 2;  // Using 0 could disguise errors.
+  // This AST id identifies the point after the declarations have been
+  // visited. We need it to capture the environment effects of declarations
+  // that emit code (function declarations).
+  static const int kDeclarationsId = 3;
 
   // Override ZoneObject's new to count allocated AST nodes.
   void* operator new(size_t size, Zone* zone) {
@@ -316,20 +320,6 @@
 };
 
 
-/**
- * A sentinel used during pre parsing that represents some expression
- * that is a valid left hand side without having to actually build
- * the expression.
- */
-class ValidLeftHandSideSentinel: public Expression {
- public:
-  explicit ValidLeftHandSideSentinel(Isolate* isolate) : Expression(isolate) {}
-  virtual bool IsValidLeftHandSide() { return true; }
-  virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
-  virtual bool IsInlineable() const;
-};
-
-
 class BreakableStatement: public Statement {
  public:
   enum Type {
@@ -404,10 +394,14 @@
 
 class Declaration: public AstNode {
  public:
-  Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
+  Declaration(VariableProxy* proxy,
+              Variable::Mode mode,
+              FunctionLiteral* fun,
+              Scope* scope)
       : proxy_(proxy),
         mode_(mode),
-        fun_(fun) {
+        fun_(fun),
+        scope_(scope) {
     ASSERT(mode == Variable::VAR ||
            mode == Variable::CONST ||
            mode == Variable::LET);
@@ -421,11 +415,15 @@
   Variable::Mode mode() const { return mode_; }
   FunctionLiteral* fun() const { return fun_; }  // may be NULL
   virtual bool IsInlineable() const;
+  Scope* scope() const { return scope_; }
 
  private:
   VariableProxy* proxy_;
   Variable::Mode mode_;
   FunctionLiteral* fun_;
+
+  // Nested scope from which the declaration originated.
+  Scope* scope_;
 };
 
 
@@ -1162,24 +1160,11 @@
                 bool is_this,
                 bool inside_with,
                 int position = RelocInfo::kNoPosition);
-  VariableProxy(Isolate* isolate, bool is_this);
 
   friend class Scope;
 };
 
 
-class VariableProxySentinel: public VariableProxy {
- public:
-  virtual bool IsValidLeftHandSide() { return !is_this(); }
-
- private:
-  VariableProxySentinel(Isolate* isolate, bool is_this)
-      : VariableProxy(isolate, is_this) { }
-
-  friend class AstSentinels;
-};
-
-
 class Slot: public Expression {
  public:
   enum Type {
@@ -1337,36 +1322,6 @@
 };
 
 
-class AstSentinels {
- public:
-  ~AstSentinels() { }
-
-  // Returns a property singleton property access on 'this'.  Used
-  // during preparsing.
-  Property* this_property() { return &this_property_; }
-  VariableProxySentinel* this_proxy() { return &this_proxy_; }
-  VariableProxySentinel* identifier_proxy() { return &identifier_proxy_; }
-  ValidLeftHandSideSentinel* valid_left_hand_side_sentinel() {
-    return &valid_left_hand_side_sentinel_;
-  }
-  Call* call_sentinel() { return &call_sentinel_; }
-  EmptyStatement* empty_statement() { return &empty_statement_; }
-
- private:
-  AstSentinels();
-  VariableProxySentinel this_proxy_;
-  VariableProxySentinel identifier_proxy_;
-  ValidLeftHandSideSentinel valid_left_hand_side_sentinel_;
-  Property this_property_;
-  Call call_sentinel_;
-  EmptyStatement empty_statement_;
-
-  friend class Isolate;
-
-  DISALLOW_COPY_AND_ASSIGN(AstSentinels);
-};
-
-
 class CallNew: public Expression {
  public:
   CallNew(Isolate* isolate,
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 9f01664..7abd45c 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -350,7 +350,14 @@
                                       prototype,
                                       call_code,
                                       is_ecma_native);
-  SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM);
+  PropertyAttributes attributes;
+  if (target->IsJSBuiltinsObject()) {
+    attributes =
+        static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
+  } else {
+    attributes = DONT_ENUM;
+  }
+  SetLocalPropertyNoThrow(target, symbol, function, attributes);
   if (is_ecma_native) {
     function->shared()->set_instance_class_name(*symbol);
   }
@@ -1677,7 +1684,6 @@
     global_context()->set_regexp_result_map(*initial_map);
   }
 
-
 #ifdef DEBUG
   builtins->Verify();
 #endif
diff --git a/src/d8.cc b/src/d8.cc
index 025c772..729ce88 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -176,8 +176,8 @@
         // If all went well and the result wasn't undefined then print
         // the returned value.
         v8::String::Utf8Value str(result);
-        const char* cstr = ToCString(str);
-        printf("%s\n", cstr);
+        fwrite(*str, sizeof(**str), str.length(), stdout);
+        printf("\n");
       }
       return true;
     }
diff --git a/src/d8.js b/src/d8.js
index a2b9585..3009037 100644
--- a/src/d8.js
+++ b/src/d8.js
@@ -1786,7 +1786,7 @@
 
 
 function decodeLolListResponse(body, title) {
-  
+
   var result;
   var total_count = body.count;
   var total_size = body.size;
diff --git a/src/date.js b/src/date.js
index 79b846d..ccefce5 100644
--- a/src/date.js
+++ b/src/date.js
@@ -1048,18 +1048,19 @@
 
 // -------------------------------------------------------------------
 
-function SetupDate() {
-  // Setup non-enumerable properties of the Date object itself.
+function SetUpDate() {
+  %CheckIsBootstrapping();
+  // Set up non-enumerable properties of the Date object itself.
   InstallFunctions($Date, DONT_ENUM, $Array(
     "UTC", DateUTC,
     "parse", DateParse,
     "now", DateNow
   ));
 
-  // Setup non-enumerable constructor property of the Date prototype object.
+  // Set up non-enumerable constructor property of the Date prototype object.
   %SetProperty($Date.prototype, "constructor", $Date, DONT_ENUM);
 
-  // Setup non-enumerable functions of the Date prototype object and
+  // Set up non-enumerable functions of the Date prototype object and
   // set their names.
   InstallFunctionsOnHiddenPrototype($Date.prototype, DONT_ENUM, $Array(
     "toString", DateToString,
@@ -1111,4 +1112,4 @@
   ));
 }
 
-SetupDate();
+SetUpDate();
diff --git a/src/extensions/externalize-string-extension.cc b/src/extensions/externalize-string-extension.cc
index b3f83fe..9fbf329 100644
--- a/src/extensions/externalize-string-extension.cc
+++ b/src/extensions/externalize-string-extension.cc
@@ -133,9 +133,11 @@
 
 
 void ExternalizeStringExtension::Register() {
-  static ExternalizeStringExtension externalize_extension;
+  static ExternalizeStringExtension* externalize_extension = NULL;
+  if (externalize_extension == NULL)
+    externalize_extension = new ExternalizeStringExtension;
   static v8::DeclareExtension externalize_extension_declaration(
-      &externalize_extension);
+      externalize_extension);
 }
 
 } }  // namespace v8::internal
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index fc7b689..0f44cf2 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -584,6 +584,15 @@
 }
 
 
+int FullCodeGenerator::DeclareGlobalsFlags() {
+  int flags = 0;
+  if (is_eval()) flags |= kDeclareGlobalsEvalFlag;
+  if (is_strict_mode()) flags |= kDeclareGlobalsStrictModeFlag;
+  if (is_native()) flags |= kDeclareGlobalsNativeFlag;
+  return flags;
+}
+
+
 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
   CodeGenerator::RecordPositions(masm_, fun->start_position());
 }
diff --git a/src/full-codegen.h b/src/full-codegen.h
index 0ed26a1..28be008 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -358,6 +358,7 @@
 
   void VisitDeclarations(ZoneList<Declaration*>* declarations);
   void DeclareGlobals(Handle<FixedArray> pairs);
+  int DeclareGlobalsFlags();
 
   // Try to perform a comparison as a fast inlined literal compare if
   // the operands allow it.  Returns true if the compare operations
@@ -402,7 +403,7 @@
 
   // Platform-specific code for a variable, constant, or function
   // declaration.  Functions have an initial value.
-  void EmitDeclaration(Variable* variable,
+  void EmitDeclaration(VariableProxy* proxy,
                        Variable::Mode mode,
                        FunctionLiteral* function);
 
@@ -555,6 +556,7 @@
 
   Handle<Script> script() { return info_->script(); }
   bool is_eval() { return info_->is_eval(); }
+  bool is_native() { return info_->is_native(); }
   bool is_strict_mode() { return function()->strict_mode(); }
   StrictModeFlag strict_mode_flag() {
     return is_strict_mode() ? kStrictMode : kNonStrictMode;
diff --git a/src/heap.cc b/src/heap.cc
index 84909d5..526fea0 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -81,14 +81,14 @@
       reserved_semispace_size_(16*MB),
       max_semispace_size_(16*MB),
       initial_semispace_size_(1*MB),
-      max_old_generation_size_(1*GB),
+      max_old_generation_size_(1400*MB),
       max_executable_size_(256*MB),
       code_range_size_(512*MB),
 #else
       reserved_semispace_size_(8*MB),
       max_semispace_size_(8*MB),
       initial_semispace_size_(512*KB),
-      max_old_generation_size_(512*MB),
+      max_old_generation_size_(700*MB),
       max_executable_size_(128*MB),
       code_range_size_(0),
 #endif
diff --git a/src/heap.h b/src/heap.h
index 0f69fab..8eb42d3 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -225,8 +225,7 @@
   V(closure_symbol, "(closure)")                                         \
   V(use_strict, "use strict")                                            \
   V(dot_symbol, ".")                                                     \
-  V(anonymous_function_symbol, "(anonymous function)")                   \
-  V(block_scope_symbol, ".block")
+  V(anonymous_function_symbol, "(anonymous function)")
 
 // Forward declarations.
 class GCTracer;
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index d3cc8a6..bbdecff 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -425,7 +425,7 @@
 
 
 void HValue::PrintChangesTo(StringStream* stream) {
-  int changes_flags = (flags() & HValue::ChangesFlagsMask());
+  int changes_flags = ChangesFlags();
   if (changes_flags == 0) return;
   stream->Add(" changes[");
   if (changes_flags == AllSideEffects()) {
@@ -512,9 +512,7 @@
 
 
 void HInstruction::PrintMnemonicTo(StringStream* stream) {
-  stream->Add("%s", Mnemonic());
-  if (HasSideEffects()) stream->Add("*");
-  stream->Add(" ");
+  stream->Add("%s ", Mnemonic());
 }
 
 
@@ -1020,11 +1018,14 @@
     value->PrintNameTo(stream);
     stream->Add(" ");
   }
-  stream->Add(" uses%d_%di_%dd_%dt]",
+  stream->Add(" uses%d_%di_%dd_%dt",
               UseCount(),
               int32_non_phi_uses() + int32_indirect_uses(),
               double_non_phi_uses() + double_indirect_uses(),
               tagged_non_phi_uses() + tagged_indirect_uses());
+  stream->Add("%s%s]",
+              is_live() ? "_live" : "",
+              IsConvertibleToInteger() ? "" : "_ncti");
 }
 
 
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 76007d7..a6b2f56 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -513,19 +513,6 @@
 
   static const int kChangesToDependsFlagsLeftShift = 1;
 
-  static int ChangesFlagsMask() {
-    int result = 0;
-    // Create changes mask.
-#define DECLARE_DO(type) result |= (1 << kChanges##type);
-  GVN_FLAG_LIST(DECLARE_DO)
-#undef DECLARE_DO
-    return result;
-  }
-
-  static int DependsFlagsMask() {
-    return ConvertChangesToDependsFlags(ChangesFlagsMask());
-  }
-
   static int ConvertChangesToDependsFlags(int flags) {
     return flags << kChangesToDependsFlagsLeftShift;
   }
@@ -629,6 +616,8 @@
   void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
   bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
 
+  int ChangesFlags() const { return flags_ & ChangesFlagsMask(); }
+
   Range* range() const { return range_; }
   bool HasRange() const { return range_ != NULL; }
   void AddNewRange(Range* r);
@@ -693,6 +682,15 @@
   }
 
  private:
+  static int ChangesFlagsMask() {
+    int result = 0;
+    // Create changes mask.
+#define ADD_FLAG(type) result |= (1 << kChanges##type);
+  GVN_FLAG_LIST(ADD_FLAG)
+#undef ADD_FLAG
+    return result;
+  }
+
   // A flag mask to mark an instruction as having arbitrary side effects.
   static int AllSideEffects() {
     return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 55bf2dc..57f5ff5 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1382,7 +1382,7 @@
     int id = block->block_id();
     int side_effects = 0;
     while (instr != NULL) {
-      side_effects |= (instr->flags() & HValue::ChangesFlagsMask());
+      side_effects |= instr->ChangesFlags();
       instr = instr->next();
     }
     block_side_effects_[id] |= side_effects;
@@ -1499,7 +1499,7 @@
   HInstruction* instr = block->first();
   while (instr != NULL) {
     HInstruction* next = instr->next();
-    int flags = (instr->flags() & HValue::ChangesFlagsMask());
+    int flags = instr->ChangesFlags();
     if (flags != 0) {
       ASSERT(!instr->CheckFlag(HValue::kUseGVN));
       // Clear all instructions in the map that are affected by side effects.
@@ -2273,10 +2273,6 @@
       return NULL;
     }
     SetupScope(scope);
-    VisitDeclarations(scope->declarations());
-    HValue* context = environment()->LookupContext();
-    AddInstruction(
-        new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry));
 
     // Add an edge to the body entry.  This is warty: the graph's start
     // environment will be used by the Lithium translation as the initial
@@ -2298,6 +2294,19 @@
     current_block()->Goto(body_entry);
     body_entry->SetJoinId(AstNode::kFunctionEntryId);
     set_current_block(body_entry);
+
+    // Handle implicit declaration of the function name in named function
+    // expressions before other declarations.
+    if (scope->is_function_scope() && scope->function() != NULL) {
+      HandleDeclaration(scope->function(), Variable::CONST, NULL);
+    }
+    VisitDeclarations(scope->declarations());
+    AddSimulate(AstNode::kDeclarationsId);
+
+    HValue* context = environment()->LookupContext();
+    AddInstruction(
+        new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry));
+
     VisitStatements(info()->function()->body());
     if (HasStackOverflow()) return NULL;
 
@@ -4800,13 +4809,15 @@
   // Found pattern f.apply(receiver, arguments).
   VisitForValue(prop->obj());
   if (HasStackOverflow() || current_block() == NULL) return true;
-  HValue* function = Pop();
+  HValue* function = Top();
+  AddCheckConstantFunction(expr, function, function_map, true);
+  Drop(1);
+
   VisitForValue(args->at(0));
   if (HasStackOverflow() || current_block() == NULL) return true;
   HValue* receiver = Pop();
   HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
   HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
-  AddCheckConstantFunction(expr, function, function_map, true);
   HInstruction* result =
       new(zone()) HApplyArguments(function, receiver, length, elements);
   result->set_position(expr->position());
@@ -5807,17 +5818,51 @@
 
 
 void HGraphBuilder::VisitDeclaration(Declaration* decl) {
-  // We support only declarations that do not require code generation.
-  Variable* var = decl->proxy()->var();
-  if (!var->IsStackAllocated() ||
-      decl->fun() != NULL ||
-      decl->mode() == Variable::LET) {
-    return Bailout("unsupported declaration");
-  }
+  HandleDeclaration(decl->proxy(), decl->mode(), decl->fun());
+}
 
-  if (decl->mode() == Variable::CONST) {
-    ASSERT(var->IsStackAllocated());
-    environment()->Bind(var, graph()->GetConstantHole());
+
+void HGraphBuilder::HandleDeclaration(VariableProxy* proxy,
+                                    Variable::Mode mode,
+                                    FunctionLiteral* function) {
+  if (mode == Variable::LET) return Bailout("unsupported let declaration");
+  Variable* var = proxy->var();
+  Slot* slot = var->AsSlot();
+  ASSERT(slot != NULL);
+  switch (slot->type()) {
+    case Slot::PARAMETER:
+    case Slot::LOCAL:
+      if (mode == Variable::CONST) {
+        environment()->Bind(var, graph()->GetConstantHole());
+      } else if (function != NULL) {
+        VisitForValue(function);
+        HValue* function_value = Pop();
+        environment()->Bind(var, function_value);
+      }
+      break;
+    case Slot::CONTEXT: {
+      HValue* context = environment()->LookupContext();
+      if (mode == Variable::CONST) {
+        HStoreContextSlot* store =
+            new HStoreContextSlot(context,
+                                  slot->index(),
+                                  graph()->GetConstantHole());
+        AddInstruction(store);
+        if (store->HasSideEffects()) AddSimulate(proxy->id());
+      } else if (function != NULL) {
+        VisitForValue(function);
+        HValue* function_value = Pop();
+        HStoreContextSlot* store =
+            new HStoreContextSlot(context,
+                                  slot->index(),
+                                  function_value);
+        AddInstruction(store);
+        if (store->HasSideEffects()) AddSimulate(proxy->id());
+      }
+      break;
+    }
+    case Slot::LOOKUP:
+      return Bailout("unsupported lookup slot in declaration");
   }
 }
 
diff --git a/src/hydrogen.h b/src/hydrogen.h
index c18ba58..b5fdf49 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -779,6 +779,10 @@
   INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
 #undef INLINE_FUNCTION_GENERATOR_DECLARATION
 
+  void HandleDeclaration(VariableProxy* proxy,
+                         Variable::Mode mode,
+                         FunctionLiteral* function);
+
   void VisitDelete(UnaryOperation* expr);
   void VisitVoid(UnaryOperation* expr);
   void VisitTypeof(UnaryOperation* expr);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 85e74b8..f3eb09f 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -4907,7 +4907,8 @@
 
   // Check for 1-byte or 2-byte string.
   __ bind(&flat_string);
-  STATIC_ASSERT(kAsciiStringTag != 0);
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
   __ test(result_, Immediate(kStringEncodingMask));
   __ j(not_zero, &ascii_string, Label::kNear);
 
@@ -5178,8 +5179,9 @@
   __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
   __ movzx_b(edi, FieldOperand(edi, Map::kInstanceTypeOffset));
   __ and_(ecx, Operand(edi));
-  STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
-  __ test(ecx, Immediate(kAsciiStringTag));
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
+  __ test(ecx, Immediate(kStringEncodingMask));
   __ j(zero, &non_ascii);
   __ bind(&ascii_data);
   // Allocate an acsii cons string.
@@ -5210,7 +5212,7 @@
   __ cmp(edi, kAsciiStringTag | kAsciiDataHintTag);
   __ j(equal, &ascii_data);
   // Allocate a two byte cons string.
-  __ AllocateConsString(ecx, edi, no_reg, &string_add_runtime);
+  __ AllocateTwoByteConsString(ecx, edi, no_reg, &string_add_runtime);
   __ jmp(&allocated);
 
   // Handle creating a flat result. First check that both strings are not
@@ -5236,12 +5238,13 @@
   // ebx: length of resulting flat string as a smi
   // edx: second string
   Label non_ascii_string_add_flat_result;
-  STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
   __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
-  __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
+  __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kStringEncodingMask);
   __ j(zero, &non_ascii_string_add_flat_result);
   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
-  __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
+  __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kStringEncodingMask);
   __ j(zero, &string_add_runtime);
 
   // Both strings are ascii strings.  As they are short they are both flat.
@@ -5281,7 +5284,7 @@
   // edx: second string
   __ bind(&non_ascii_string_add_flat_result);
   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
-  __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
+  __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kStringEncodingMask);
   __ j(not_zero, &string_add_runtime);
   // Both strings are two byte strings. As they are short they are both
   // flat.
@@ -5759,13 +5762,14 @@
     // string's encoding is wrong because we always have to recheck encoding of
     // the newly created string's parent anyways due to externalized strings.
     Label two_byte_slice, set_slice_header;
-    STATIC_ASSERT(kAsciiStringTag != 0);
-    __ test(ebx, Immediate(kAsciiStringTag));
+    STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+    STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
+    __ test(ebx, Immediate(kStringEncodingMask));
     __ j(zero, &two_byte_slice, Label::kNear);
     __ AllocateAsciiSlicedString(eax, ebx, no_reg, &runtime);
     __ jmp(&set_slice_header, Label::kNear);
     __ bind(&two_byte_slice);
-    __ AllocateSlicedString(eax, ebx, no_reg, &runtime);
+    __ AllocateTwoByteSlicedString(eax, ebx, no_reg, &runtime);
     __ bind(&set_slice_header);
     __ mov(FieldOperand(eax, SlicedString::kOffsetOffset), edx);
     __ SmiTag(ecx);
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 52e33d6..a0e4faa 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -255,6 +255,7 @@
     scope()->VisitIllegalRedeclaration(this);
 
   } else {
+    PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
     { Comment cmnt(masm_, "[ Declarations");
       // For named function expressions, declare the function name as a
       // constant.
@@ -265,7 +266,7 @@
     }
 
     { Comment cmnt(masm_, "[ Stack check");
-      PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
+      PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
       Label ok;
       ExternalReference stack_limit =
           ExternalReference::address_of_stack_limit(isolate());
@@ -683,10 +684,11 @@
 }
 
 
-void FullCodeGenerator::EmitDeclaration(Variable* variable,
+void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
                                         Variable::Mode mode,
                                         FunctionLiteral* function) {
   Comment cmnt(masm_, "[ Declaration");
+  Variable* variable = proxy->var();
   ASSERT(variable != NULL);  // Must have been resolved.
   Slot* slot = variable->AsSlot();
   ASSERT(slot != NULL);
@@ -723,10 +725,12 @@
         int offset = Context::SlotOffset(slot->index());
         __ mov(ebx, esi);
         __ RecordWrite(ebx, offset, result_register(), ecx);
+        PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
       } else if (mode == Variable::CONST || mode == Variable::LET) {
         __ mov(ContextOperand(esi, slot->index()),
                Immediate(isolate()->factory()->the_hole_value()));
         // No write barrier since the hole value is in old space.
+        PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
       }
       break;
 
@@ -762,7 +766,7 @@
 
 
 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
-  EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
+  EmitDeclaration(decl->proxy(), decl->mode(), decl->fun());
 }
 
 
@@ -770,9 +774,8 @@
   // Call the runtime to declare the globals.
   __ push(esi);  // The context is the first argument.
   __ push(Immediate(pairs));
-  __ push(Immediate(Smi::FromInt(is_eval() ? 1 : 0)));
-  __ push(Immediate(Smi::FromInt(strict_mode_flag())));
-  __ CallRuntime(Runtime::kDeclareGlobals, 4);
+  __ push(Immediate(Smi::FromInt(DeclareGlobalsFlags())));
+  __ CallRuntime(Runtime::kDeclareGlobals, 3);
   // Return value is ignored.
 }
 
@@ -2157,8 +2160,13 @@
   // Push the receiver of the enclosing function.
   __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize));
 
-  // Push the strict mode flag.
-  __ push(Immediate(Smi::FromInt(strict_mode_flag())));
+  // Push the strict mode flag. In harmony mode every eval call
+  // is a strict mode eval call.
+  StrictModeFlag strict_mode = strict_mode_flag();
+  if (FLAG_harmony_block_scoping) {
+    strict_mode = kStrictMode;
+  }
+  __ push(Immediate(Smi::FromInt(strict_mode)));
 
   __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
                  ? Runtime::kResolvePossiblyDirectEvalNoLookup
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 32e3074..7136105 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3269,7 +3269,8 @@
 
   // Dispatch on the encoding: ASCII or two-byte.
   Label ascii_string;
-  STATIC_ASSERT(kAsciiStringTag != 0);
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
   __ test(result, Immediate(kStringEncodingMask));
   __ j(not_zero, &ascii_string, Label::kNear);
 
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index dff174c..6d3ce2b 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -1172,7 +1172,7 @@
 }
 
 
-void MacroAssembler::AllocateConsString(Register result,
+void MacroAssembler::AllocateTwoByteConsString(Register result,
                                         Register scratch1,
                                         Register scratch2,
                                         Label* gc_required) {
@@ -1208,7 +1208,7 @@
 }
 
 
-void MacroAssembler::AllocateSlicedString(Register result,
+void MacroAssembler::AllocateTwoByteSlicedString(Register result,
                                           Register scratch1,
                                           Register scratch2,
                                           Label* gc_required) {
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index de9361d..1906644 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -437,7 +437,7 @@
 
   // Allocate a raw cons string object. Only the map field of the result is
   // initialized.
-  void AllocateConsString(Register result,
+  void AllocateTwoByteConsString(Register result,
                           Register scratch1,
                           Register scratch2,
                           Label* gc_required);
@@ -448,7 +448,7 @@
 
   // Allocate a raw sliced string object. Only the map field of the result is
   // initialized.
-  void AllocateSlicedString(Register result,
+  void AllocateTwoByteSlicedString(Register result,
                             Register scratch1,
                             Register scratch2,
                             Label* gc_required);
diff --git a/src/isolate.cc b/src/isolate.cc
index 09cbc8a..d366902 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1409,7 +1409,6 @@
       global_handles_(NULL),
       context_switcher_(NULL),
       thread_manager_(NULL),
-      ast_sentinels_(NULL),
       string_tracker_(NULL),
       regexp_stack_(NULL),
       embedder_data_(NULL) {
@@ -1546,9 +1545,6 @@
   delete regexp_stack_;
   regexp_stack_ = NULL;
 
-  delete ast_sentinels_;
-  ast_sentinels_ = NULL;
-
   delete descriptor_lookup_cache_;
   descriptor_lookup_cache_ = NULL;
   delete context_slot_cache_;
@@ -1710,7 +1706,6 @@
   bootstrapper_ = new Bootstrapper();
   handle_scope_implementer_ = new HandleScopeImplementer(this);
   stub_cache_ = new StubCache(this);
-  ast_sentinels_ = new AstSentinels();
   regexp_stack_ = new RegExpStack();
   regexp_stack_->isolate_ = this;
 
diff --git a/src/isolate.h b/src/isolate.h
index 5bb504d..7c690d2 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -47,7 +47,6 @@
 namespace v8 {
 namespace internal {
 
-class AstSentinels;
 class Bootstrapper;
 class CodeGenerator;
 class CodeRange;
@@ -878,8 +877,6 @@
     return &objects_string_input_buffer_;
   }
 
-  AstSentinels* ast_sentinels() { return ast_sentinels_; }
-
   RuntimeState* runtime_state() { return &runtime_state_; }
 
   StaticResource<SafeStringInputBuffer>* compiler_safe_string_input_buffer() {
@@ -1138,7 +1135,6 @@
   GlobalHandles* global_handles_;
   ContextSwitcher* context_switcher_;
   ThreadManager* thread_manager_;
-  AstSentinels* ast_sentinels_;
   RuntimeState runtime_state_;
   StaticResource<SafeStringInputBuffer> compiler_safe_string_input_buffer_;
   Builtins builtins_;
diff --git a/src/json.js b/src/json.js
index 8fd410f..a491bcc 100644
--- a/src/json.js
+++ b/src/json.js
@@ -337,11 +337,12 @@
   return JSONSerialize('', {'': value}, replacer, new InternalArray(), "", gap);
 }
 
-function SetupJSON() {
+function SetUpJSON() {
+  %CheckIsBootstrapping();
   InstallFunctions($JSON, DONT_ENUM, $Array(
     "parse", JSONParse,
     "stringify", JSONStringify
   ));
 }
 
-SetupJSON();
+SetUpJSON()
diff --git a/src/macros.py b/src/macros.py
index 5ba7ac3..ec6a251 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -170,7 +170,7 @@
 const CAPTURE0 = 3;
 const CAPTURE1 = 4;
 
-# PropertyDescriptor return value indices - must match 
+# PropertyDescriptor return value indices - must match
 # PropertyDescriptorIndices in runtime.cc.
 const IS_ACCESSOR_INDEX = 0;
 const VALUE_INDEX = 1;
@@ -179,3 +179,17 @@
 const WRITABLE_INDEX = 4;
 const ENUMERABLE_INDEX = 5;
 const CONFIGURABLE_INDEX = 6;
+
+# For messages.js
+# Matches Script::Type from objects.h
+const TYPE_NATIVE = 0;
+const TYPE_EXTENSION = 1;
+const TYPE_NORMAL = 2;
+
+# Matches Script::CompilationType from objects.h
+const COMPILATION_TYPE_HOST = 0;
+const COMPILATION_TYPE_EVAL = 1;
+const COMPILATION_TYPE_JSON = 2;
+
+# Matches Messages::kNoLineNumberInfo from v8.h
+const kNoLineNumberInfo = 0;
diff --git a/src/math.js b/src/math.js
index 70b8c57..b5a6d18 100644
--- a/src/math.js
+++ b/src/math.js
@@ -38,7 +38,7 @@
 function MathConstructor() {}
 %FunctionSetInstanceClassName(MathConstructor, 'Math');
 const $Math = new MathConstructor();
-$Math.__proto__ = global.Object.prototype;
+$Math.__proto__ = $Object.prototype;
 %SetProperty(global, "Math", $Math, DONT_ENUM);
 
 // ECMA 262 - 15.8.2.1
@@ -195,8 +195,9 @@
 
 // -------------------------------------------------------------------
 
-function SetupMath() {
-  // Setup math constants.
+function SetUpMath() {
+  %CheckIsBootstrapping();
+  // Set up math constants.
   // ECMA-262, section 15.8.1.1.
   %OptimizeObjectForAddingMultipleProperties($Math, 8);
   %SetProperty($Math,
@@ -236,7 +237,7 @@
                DONT_ENUM |  DONT_DELETE | READ_ONLY);
   %ToFastProperties($Math);
 
-  // Setup non-enumerable functions of the Math object and
+  // Set up non-enumerable functions of the Math object and
   // set their names.
   InstallFunctionsOnHiddenPrototype($Math, DONT_ENUM, $Array(
     "random", MathRandom,
@@ -258,7 +259,6 @@
     "max", MathMax,
     "min", MathMin
   ));
-};
+}
 
-
-SetupMath();
+SetUpMath();
diff --git a/src/messages.js b/src/messages.js
index cbbb70e..3c85d94 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -28,27 +28,14 @@
 
 // -------------------------------------------------------------------
 //
-// Matches Script::Type from objects.h
-var TYPE_NATIVE = 0;
-var TYPE_EXTENSION = 1;
-var TYPE_NORMAL = 2;
-
-// Matches Script::CompilationType from objects.h
-var COMPILATION_TYPE_HOST = 0;
-var COMPILATION_TYPE_EVAL = 1;
-var COMPILATION_TYPE_JSON = 2;
-
-// Matches Messages::kNoLineNumberInfo from v8.h
-var kNoLineNumberInfo = 0;
-
 // If this object gets passed to an error constructor the error will
 // get an accessor for .message that constructs a descriptive error
 // message on access.
-var kAddMessageAccessorsMarker = { };
+const kAddMessageAccessorsMarker = { };
 
-var kMessages = 0;
-
-var kReplacementMarkers = [ "%0", "%1", "%2", "%3" ];
+// This will be lazily initialized when first needed (and forcibly
+// overwritten even though it's const).
+const kMessages = 0;
 
 function FormatString(format, message) {
   var args = %MessageGetArguments(message);
@@ -56,14 +43,16 @@
   var arg_num = 0;
   for (var i = 0; i < format.length; i++) {
     var str = format[i];
-    for (arg_num = 0; arg_num < kReplacementMarkers.length; arg_num++) {
-      if (str == kReplacementMarkers[arg_num]) {
+    if (str.length == 2 && %_StringCharCodeAt(str, 0) == 0x25) {
+      // Two-char string starts with "%".
+      var arg_num = (%_StringCharCodeAt(str, 1) - 0x30) >>> 0;
+      if (arg_num < 4) {
+        // str is one of %0, %1, %2 or %3.
         try {
           str = ToDetailString(args[arg_num]);
         } catch (e) {
           str = "#<error>";
         }
-        break;
       }
     }
     result += str;
@@ -102,18 +91,16 @@
 
 
 function ToDetailString(obj) {
-  if (obj != null && IS_OBJECT(obj) &&
-      obj.toString === $Object.prototype.toString) {
+  if (obj != null && IS_OBJECT(obj) && obj.toString === ObjectToString) {
     var constructor = obj.constructor;
-    if (!constructor) return ToStringCheckErrorObject(obj);
-    var constructorName = constructor.name;
-    if (!constructorName || !IS_STRING(constructorName)) {
-      return ToStringCheckErrorObject(obj);
+    if (typeof constructor == "function") {
+      var constructorName = constructor.name;
+      if (IS_STRING(constructorName) && constructorName !== "") {
+        return "#<" + constructorName + ">";
+      }
     }
-    return "#<" + constructorName + ">";
-  } else {
-    return ToStringCheckErrorObject(obj);
   }
+  return ToStringCheckErrorObject(obj);
 }
 
 
@@ -129,10 +116,11 @@
 
 
 /**
- * Setup the Script function and constructor.
+ * Set up the Script function and constructor.
  */
 %FunctionSetInstanceClassName(Script, 'Script');
-%SetProperty(Script.prototype, 'constructor', Script, DONT_ENUM);
+%SetProperty(Script.prototype, 'constructor', Script,
+             DONT_ENUM | DONT_DELETE | READ_ONLY);
 %SetCode(Script, function(x) {
   // Script objects can only be created by the VM.
   throw new $Error("Not supported");
@@ -142,116 +130,132 @@
 // Helper functions; called from the runtime system.
 function FormatMessage(message) {
   if (kMessages === 0) {
-    kMessages = {
+    var messagesDictionary = [
       // Error
-      cyclic_proto:                 ["Cyclic __proto__ value"],
-      code_gen_from_strings:        ["Code generation from strings disallowed for this context"],
+      "cyclic_proto",                 ["Cyclic __proto__ value"],
+      "code_gen_from_strings",        ["Code generation from strings disallowed for this context"],
       // TypeError
-      unexpected_token:             ["Unexpected token ", "%0"],
-      unexpected_token_number:      ["Unexpected number"],
-      unexpected_token_string:      ["Unexpected string"],
-      unexpected_token_identifier:  ["Unexpected identifier"],
-      unexpected_reserved:          ["Unexpected reserved word"],
-      unexpected_strict_reserved:   ["Unexpected strict mode reserved word"],
-      unexpected_eos:               ["Unexpected end of input"],
-      malformed_regexp:             ["Invalid regular expression: /", "%0", "/: ", "%1"],
-      unterminated_regexp:          ["Invalid regular expression: missing /"],
-      regexp_flags:                 ["Cannot supply flags when constructing one RegExp from another"],
-      incompatible_method_receiver: ["Method ", "%0", " called on incompatible receiver ", "%1"],
-      invalid_lhs_in_assignment:    ["Invalid left-hand side in assignment"],
-      invalid_lhs_in_for_in:        ["Invalid left-hand side in for-in"],
-      invalid_lhs_in_postfix_op:    ["Invalid left-hand side expression in postfix operation"],
-      invalid_lhs_in_prefix_op:     ["Invalid left-hand side expression in prefix operation"],
-      multiple_defaults_in_switch:  ["More than one default clause in switch statement"],
-      newline_after_throw:          ["Illegal newline after throw"],
-      redeclaration:                ["%0", " '", "%1", "' has already been declared"],
-      no_catch_or_finally:          ["Missing catch or finally after try"],
-      unknown_label:                ["Undefined label '", "%0", "'"],
-      uncaught_exception:           ["Uncaught ", "%0"],
-      stack_trace:                  ["Stack Trace:\n", "%0"],
-      called_non_callable:          ["%0", " is not a function"],
-      undefined_method:             ["Object ", "%1", " has no method '", "%0", "'"],
-      property_not_function:        ["Property '", "%0", "' of object ", "%1", " is not a function"],
-      cannot_convert_to_primitive:  ["Cannot convert object to primitive value"],
-      not_constructor:              ["%0", " is not a constructor"],
-      not_defined:                  ["%0", " is not defined"],
-      non_object_property_load:     ["Cannot read property '", "%0", "' of ", "%1"],
-      non_object_property_store:    ["Cannot set property '", "%0", "' of ", "%1"],
-      non_object_property_call:     ["Cannot call method '", "%0", "' of ", "%1"],
-      with_expression:              ["%0", " has no properties"],
-      illegal_invocation:           ["Illegal invocation"],
-      no_setter_in_callback:        ["Cannot set property ", "%0", " of ", "%1", " which has only a getter"],
-      apply_non_function:           ["Function.prototype.apply was called on ", "%0", ", which is a ", "%1", " and not a function"],
-      apply_wrong_args:             ["Function.prototype.apply: Arguments list has wrong type"],
-      invalid_in_operator_use:      ["Cannot use 'in' operator to search for '", "%0", "' in ", "%1"],
-      instanceof_function_expected: ["Expecting a function in instanceof check, but got ", "%0"],
-      instanceof_nonobject_proto:   ["Function has non-object prototype '", "%0", "' in instanceof check"],
-      null_to_object:               ["Cannot convert null to object"],
-      reduce_no_initial:            ["Reduce of empty array with no initial value"],
-      getter_must_be_callable:      ["Getter must be a function: ", "%0"],
-      setter_must_be_callable:      ["Setter must be a function: ", "%0"],
-      value_and_accessor:           ["Invalid property.  A property cannot both have accessors and be writable or have a value: ", "%0"],
-      proto_object_or_null:         ["Object prototype may only be an Object or null"],
-      property_desc_object:         ["Property description must be an object: ", "%0"],
-      redefine_disallowed:          ["Cannot redefine property: ", "%0"],
-      define_disallowed:            ["Cannot define property:", "%0", ", object is not extensible."],
-      non_extensible_proto:         ["%0", " is not extensible"],
-      handler_non_object:           ["Proxy.", "%0", " called with non-object as handler"],
-      handler_trap_missing:         ["Proxy handler ", "%0", " has no '", "%1", "' trap"],
-      handler_trap_must_be_callable: ["Proxy handler ", "%0", " has non-callable '", "%1", "' trap"],
-      handler_returned_false:       ["Proxy handler ", "%0", " returned false for '", "%1", "' trap"],
-      handler_returned_undefined:   ["Proxy handler ", "%0", " returned undefined for '", "%1", "' trap"],
-      proxy_prop_not_configurable:  ["Trap ", "%1", " of proxy handler ", "%0", " returned non-configurable descriptor for property ", "%2"],
-      proxy_non_object_prop_names:  ["Trap ", "%1", " returned non-object ", "%0"],
-      proxy_repeated_prop_name:     ["Trap ", "%1", " returned repeated property name ", "%2"],
-      invalid_weakmap_key:          ["Invalid value used as weak map key"],
+      "unexpected_token",             ["Unexpected token ", "%0"],
+      "unexpected_token_number",      ["Unexpected number"],
+      "unexpected_token_string",      ["Unexpected string"],
+      "unexpected_token_identifier",  ["Unexpected identifier"],
+      "unexpected_reserved",          ["Unexpected reserved word"],
+      "unexpected_strict_reserved",   ["Unexpected strict mode reserved word"],
+      "unexpected_eos",               ["Unexpected end of input"],
+      "malformed_regexp",             ["Invalid regular expression: /", "%0", "/: ", "%1"],
+      "unterminated_regexp",          ["Invalid regular expression: missing /"],
+      "regexp_flags",                 ["Cannot supply flags when constructing one RegExp from another"],
+      "incompatible_method_receiver", ["Method ", "%0", " called on incompatible receiver ", "%1"],
+      "invalid_lhs_in_assignment",    ["Invalid left-hand side in assignment"],
+      "invalid_lhs_in_for_in",        ["Invalid left-hand side in for-in"],
+      "invalid_lhs_in_postfix_op",    ["Invalid left-hand side expression in postfix operation"],
+      "invalid_lhs_in_prefix_op",     ["Invalid left-hand side expression in prefix operation"],
+      "multiple_defaults_in_switch",  ["More than one default clause in switch statement"],
+      "newline_after_throw",          ["Illegal newline after throw"],
+      "redeclaration",                ["%0", " '", "%1", "' has already been declared"],
+      "no_catch_or_finally",          ["Missing catch or finally after try"],
+      "unknown_label",                ["Undefined label '", "%0", "'"],
+      "uncaught_exception",           ["Uncaught ", "%0"],
+      "stack_trace",                  ["Stack Trace:\n", "%0"],
+      "called_non_callable",          ["%0", " is not a function"],
+      "undefined_method",             ["Object ", "%1", " has no method '", "%0", "'"],
+      "property_not_function",        ["Property '", "%0", "' of object ", "%1", " is not a function"],
+      "cannot_convert_to_primitive",  ["Cannot convert object to primitive value"],
+      "not_constructor",              ["%0", " is not a constructor"],
+      "not_defined",                  ["%0", " is not defined"],
+      "non_object_property_load",     ["Cannot read property '", "%0", "' of ", "%1"],
+      "non_object_property_store",    ["Cannot set property '", "%0", "' of ", "%1"],
+      "non_object_property_call",     ["Cannot call method '", "%0", "' of ", "%1"],
+      "with_expression",              ["%0", " has no properties"],
+      "illegal_invocation",           ["Illegal invocation"],
+      "no_setter_in_callback",        ["Cannot set property ", "%0", " of ", "%1", " which has only a getter"],
+      "apply_non_function",           ["Function.prototype.apply was called on ", "%0", ", which is a ", "%1", " and not a function"],
+      "apply_wrong_args",             ["Function.prototype.apply: Arguments list has wrong type"],
+      "invalid_in_operator_use",      ["Cannot use 'in' operator to search for '", "%0", "' in ", "%1"],
+      "instanceof_function_expected", ["Expecting a function in instanceof check, but got ", "%0"],
+      "instanceof_nonobject_proto",   ["Function has non-object prototype '", "%0", "' in instanceof check"],
+      "null_to_object",               ["Cannot convert null to object"],
+      "reduce_no_initial",            ["Reduce of empty array with no initial value"],
+      "getter_must_be_callable",      ["Getter must be a function: ", "%0"],
+      "setter_must_be_callable",      ["Setter must be a function: ", "%0"],
+      "value_and_accessor",           ["Invalid property.  A property cannot both have accessors and be writable or have a value, ", "%0"],
+      "proto_object_or_null",         ["Object prototype may only be an Object or null"],
+      "property_desc_object",         ["Property description must be an object: ", "%0"],
+      "redefine_disallowed",          ["Cannot redefine property: ", "%0"],
+      "define_disallowed",            ["Cannot define property:", "%0", ", object is not extensible."],
+      "non_extensible_proto",         ["%0", " is not extensible"],
+      "handler_non_object",           ["Proxy.", "%0", " called with non-object as handler"],
+      "handler_trap_missing",         ["Proxy handler ", "%0", " has no '", "%1", "' trap"],
+      "handler_trap_must_be_callable", ["Proxy handler ", "%0", " has non-callable '", "%1", "' trap"],
+      "handler_returned_false",       ["Proxy handler ", "%0", " returned false for '", "%1", "' trap"],
+      "handler_returned_undefined",   ["Proxy handler ", "%0", " returned undefined for '", "%1", "' trap"],
+      "proxy_prop_not_configurable",  ["Trap ", "%1", " of proxy handler ", "%0", " returned non-configurable descriptor for property ", "%2"],
+      "proxy_non_object_prop_names",  ["Trap ", "%1", " returned non-object ", "%0"],
+      "proxy_repeated_prop_name",     ["Trap ", "%1", " returned repeated property name ", "%2"],
+      "invalid_weakmap_key",          ["Invalid value used as weak map key"],
       // RangeError
-      invalid_array_length:         ["Invalid array length"],
-      stack_overflow:               ["Maximum call stack size exceeded"],
+      "invalid_array_length",         ["Invalid array length"],
+      "stack_overflow",               ["Maximum call stack size exceeded"],
       // SyntaxError
-      unable_to_parse:              ["Parse error"],
-      invalid_regexp_flags:         ["Invalid flags supplied to RegExp constructor '", "%0", "'"],
-      invalid_regexp:               ["Invalid RegExp pattern /", "%0", "/"],
-      illegal_break:                ["Illegal break statement"],
-      illegal_continue:             ["Illegal continue statement"],
-      illegal_return:               ["Illegal return statement"],
-      error_loading_debugger:       ["Error loading debugger"],
-      no_input_to_regexp:           ["No input to ", "%0"],
-      invalid_json:                 ["String '", "%0", "' is not valid JSON"],
-      circular_structure:           ["Converting circular structure to JSON"],
-      obj_ctor_property_non_object: ["Object.", "%0", " called on non-object"],
-      called_on_null_or_undefined:  ["%0", " called on null or undefined"],
-      array_indexof_not_defined:    ["Array.getIndexOf: Argument undefined"],
-      object_not_extensible:        ["Can't add property ", "%0", ", object is not extensible"],
-      illegal_access:               ["Illegal access"],
-      invalid_preparser_data:       ["Invalid preparser data for function ", "%0"],
-      strict_mode_with:             ["Strict mode code may not include a with statement"],
-      strict_catch_variable:        ["Catch variable may not be eval or arguments in strict mode"],
-      too_many_arguments:           ["Too many arguments in function call (only 32766 allowed)"],
-      too_many_parameters:          ["Too many parameters in function definition (only 32766 allowed)"],
-      too_many_variables:           ["Too many variables declared (only 32767 allowed)"],
-      strict_param_name:            ["Parameter name eval or arguments is not allowed in strict mode"],
-      strict_param_dupe:            ["Strict mode function may not have duplicate parameter names"],
-      strict_var_name:              ["Variable name may not be eval or arguments in strict mode"],
-      strict_function_name:         ["Function name may not be eval or arguments in strict mode"],
-      strict_octal_literal:         ["Octal literals are not allowed in strict mode."],
-      strict_duplicate_property:    ["Duplicate data property in object literal not allowed in strict mode"],
-      accessor_data_property:       ["Object literal may not have data and accessor property with the same name"],
-      accessor_get_set:             ["Object literal may not have multiple get/set accessors with the same name"],
-      strict_lhs_assignment:        ["Assignment to eval or arguments is not allowed in strict mode"],
-      strict_lhs_postfix:           ["Postfix increment/decrement may not have eval or arguments operand in strict mode"],
-      strict_lhs_prefix:            ["Prefix increment/decrement may not have eval or arguments operand in strict mode"],
-      strict_reserved_word:         ["Use of future reserved word in strict mode"],
-      strict_delete:                ["Delete of an unqualified identifier in strict mode."],
-      strict_delete_property:       ["Cannot delete property '", "%0", "' of ", "%1"],
-      strict_const:                 ["Use of const in strict mode."],
-      strict_function:              ["In strict mode code, functions can only be declared at top level or immediately within another function." ],
-      strict_read_only_property:    ["Cannot assign to read only property '", "%0", "' of ", "%1"],
-      strict_cannot_assign:         ["Cannot assign to read only '", "%0", "' in strict mode"],
-      strict_poison_pill:           ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"],
-      strict_caller:                ["Illegal access to a strict mode caller function."],
-      unprotected_let:              ["Illegal let declaration in unprotected statement context."],
-    };
+      "unable_to_parse",              ["Parse error"],
+      "invalid_regexp_flags",         ["Invalid flags supplied to RegExp constructor '", "%0", "'"],
+      "invalid_regexp",               ["Invalid RegExp pattern /", "%0", "/"],
+      "illegal_break",                ["Illegal break statement"],
+      "illegal_continue",             ["Illegal continue statement"],
+      "illegal_return",               ["Illegal return statement"],
+      "error_loading_debugger",       ["Error loading debugger"],
+      "no_input_to_regexp",           ["No input to ", "%0"],
+      "invalid_json",                 ["String '", "%0", "' is not valid JSON"],
+      "circular_structure",           ["Converting circular structure to JSON"],
+      "obj_ctor_property_non_object", ["Object.", "%0", " called on non-object"],
+      "called_on_null_or_undefined",  ["%0", " called on null or undefined"],
+      "array_indexof_not_defined",    ["Array.getIndexOf: Argument undefined"],
+      "object_not_extensible",        ["Can't add property ", "%0", ", object is not extensible"],
+      "illegal_access",               ["Illegal access"],
+      "invalid_preparser_data",       ["Invalid preparser data for function ", "%0"],
+      "strict_mode_with",             ["Strict mode code may not include a with statement"],
+      "strict_catch_variable",        ["Catch variable may not be eval or arguments in strict mode"],
+      "too_many_arguments",           ["Too many arguments in function call (only 32766 allowed)"],
+      "too_many_parameters",          ["Too many parameters in function definition (only 32766 allowed)"],
+      "too_many_variables",           ["Too many variables declared (only 32767 allowed)"],
+      "strict_param_name",            ["Parameter name eval or arguments is not allowed in strict mode"],
+      "strict_param_dupe",            ["Strict mode function may not have duplicate parameter names"],
+      "strict_var_name",              ["Variable name may not be eval or arguments in strict mode"],
+      "strict_function_name",         ["Function name may not be eval or arguments in strict mode"],
+      "strict_octal_literal",         ["Octal literals are not allowed in strict mode."],
+      "strict_duplicate_property",    ["Duplicate data property in object literal not allowed in strict mode"],
+      "accessor_data_property",       ["Object literal may not have data and accessor property with the same name"],
+      "accessor_get_set",             ["Object literal may not have multiple get/set accessors with the same name"],
+      "strict_lhs_assignment",        ["Assignment to eval or arguments is not allowed in strict mode"],
+      "strict_lhs_postfix",           ["Postfix increment/decrement may not have eval or arguments operand in strict mode"],
+      "strict_lhs_prefix",            ["Prefix increment/decrement may not have eval or arguments operand in strict mode"],
+      "strict_reserved_word",         ["Use of future reserved word in strict mode"],
+      "strict_delete",                ["Delete of an unqualified identifier in strict mode."],
+      "strict_delete_property",       ["Cannot delete property '", "%0", "' of ", "%1"],
+      "strict_const",                 ["Use of const in strict mode."],
+      "strict_function",              ["In strict mode code, functions can only be declared at top level or immediately within another function." ],
+      "strict_read_only_property",    ["Cannot assign to read only property '", "%0", "' of ", "%1"],
+      "strict_cannot_assign",         ["Cannot assign to read only '", "%0", "' in strict mode"],
+      "strict_poison_pill",           ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"],
+      "strict_caller",                ["Illegal access to a strict mode caller function."],
+      "unprotected_let",              ["Illegal let declaration in unprotected statement context."],
+    ];
+    var messages = { __proto__ : null };
+    var desc = new PropertyDescriptor();
+    desc.setConfigurable(false);
+    desc.setEnumerable(false);
+    desc.setWritable(false);
+    for (var i = 0; i < messagesDictionary.length; i += 2) {
+      var key = messagesDictionary[i];
+      var format = messagesDictionary[i + 1];
+      ObjectFreeze(format);
+      desc.setValue(format);
+      DefineOwnProperty(messages, key, desc);
+    }
+    %PreventExtensions(messages);
+    %IgnoreAttributesAndSetProperty(builtins, "kMessages",
+                                    messages,
+                                    DONT_DELETE | DONT_ENUM | READ_ONLY);
   }
   var message_type = %MessageGetType(message);
   var format = kMessages[message_type];
@@ -317,7 +321,7 @@
  * @return {number} 0 if input too small, -1 if input too large,
        else the line number.
  */
-Script.prototype.lineFromPosition = function(position) {
+function ScriptLineFromPosition(position) {
   var lower = 0;
   var upper = this.lineCount() - 1;
   var line_ends = this.line_ends;
@@ -356,8 +360,8 @@
  * @return {SourceLocation}
  *     If line is negative or not in the source null is returned.
  */
-Script.prototype.locationFromPosition = function (position,
-                                                  include_resource_offset) {
+function ScriptLocationFromPosition(position,
+                                    include_resource_offset) {
   var line = this.lineFromPosition(position);
   if (line == -1) return null;
 
@@ -365,7 +369,9 @@
   var line_ends = this.line_ends;
   var start = line == 0 ? 0 : line_ends[line - 1] + 1;
   var end = line_ends[line];
-  if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') end--;
+  if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') {
+    end--;
+  }
   var column = position - start;
 
   // Adjust according to the offset within the resource.
@@ -390,11 +396,12 @@
  * @param {number} opt_line The line within the source. Default value is 0
  * @param {number} opt_column The column in within the line. Default value is 0
  * @param {number} opt_offset_position The offset from the begining of the
- *     source from where the line and column calculation starts. Default value is 0
+ *     source from where the line and column calculation starts.
+ *     Default value is 0
  * @return {SourceLocation}
  *     If line is negative or not in the source null is returned.
  */
-Script.prototype.locationFromLine = function (opt_line, opt_column, opt_offset_position) {
+function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) {
   // Default is the first line in the script. Lines in the script is relative
   // to the offset within the resource.
   var line = 0;
@@ -436,7 +443,7 @@
  * @return {SourceSlice} The source slice or null of the parameters where
  *     invalid
  */
-Script.prototype.sourceSlice = function (opt_from_line, opt_to_line) {
+function ScriptSourceSlice(opt_from_line, opt_to_line) {
   var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line;
   var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount() : opt_to_line
 
@@ -463,7 +470,7 @@
 }
 
 
-Script.prototype.sourceLine = function (opt_line) {
+function ScriptSourceLine(opt_line) {
   // Default is the first line in the script. Lines in the script are relative
   // to the offset within the resource.
   var line = 0;
@@ -489,7 +496,7 @@
  * @return {number}
  *     Number of source lines.
  */
-Script.prototype.lineCount = function() {
+function ScriptLineCount() {
   // Return number of source lines.
   return this.line_ends.length;
 };
@@ -505,9 +512,10 @@
  * @return {?string} script name if present, value for //@ sourceURL comment
  * otherwise.
  */
-Script.prototype.nameOrSourceURL = function() {
-  if (this.name)
+function ScriptNameOrSourceURL() {
+  if (this.name) {
     return this.name;
+  }
   // TODO(608): the spaces in a regexp below had to be escaped as \040
   // because this file is being processed by js2c whose handling of spaces
   // in regexps is broken. Also, ['"] are excluded from allowed URLs to
@@ -533,6 +541,20 @@
 }
 
 
+SetUpLockedPrototype(Script,
+  $Array("source", "name", "line_ends", "line_offset", "column_offset"),
+  $Array(
+    "lineFromPosition", ScriptLineFromPosition,
+    "locationFromPosition", ScriptLocationFromPosition,
+    "locationFromLine", ScriptLocationFromLine,
+    "sourceSlice", ScriptSourceSlice,
+    "sourceLine", ScriptSourceLine,
+    "lineCount", ScriptLineCount,
+    "nameOrSourceURL", ScriptNameOrSourceURL
+  )
+);
+
+
 /**
  * Class for source location. A source location is a position within some
  * source with the following properties:
@@ -563,8 +585,6 @@
   this.end = end;
 }
 
-SourceLocation.prototype.__proto__ = null;
-
 const kLineLengthLimit = 78;
 
 /**
@@ -575,7 +595,7 @@
  * @param {number} opt_before The number of characters to prefer before the
  *     position with a default value of 10 less that the limit
  */
-SourceLocation.prototype.restrict = function (opt_limit, opt_before) {
+function SourceLocationRestrict(opt_limit, opt_before) {
   // Find the actual limit to use.
   var limit;
   var before;
@@ -622,11 +642,20 @@
  * @return {String}
  *     Source text for this location.
  */
-SourceLocation.prototype.sourceText = function () {
+function SourceLocationSourceText() {
   return %_CallFunction(this.script.source, this.start, this.end, StringSubstring);
 };
 
 
+SetUpLockedPrototype(SourceLocation,
+  $Array("script", "position", "line", "column", "start", "end"),
+  $Array(
+    "restrict", SourceLocationRestrict,
+    "sourceText", SourceLocationSourceText
+  )
+);
+
+
 /**
  * Class for a source slice. A source slice is a part of a script source with
  * the following properties:
@@ -653,20 +682,23 @@
   this.to_position = to_position;
 }
 
-SourceSlice.prototype.__proto__ = null;
-
 /**
  * Get the source text for a SourceSlice
  * @return {String} Source text for this slice. The last line will include
  *     the line terminating characters (if any)
  */
-SourceSlice.prototype.sourceText = function () {
+function SourceSliceSourceText() {
   return %_CallFunction(this.script.source,
                         this.from_position,
                         this.to_position,
                         StringSubstring);
 };
 
+SetUpLockedPrototype(SourceSlice,
+  $Array("script", "from_line", "to_line", "from_position", "to_position"),
+  $Array("sourceText", SourceSliceSourceText)
+);
+
 
 // Returns the offset of the given position within the containing
 // line.
@@ -721,13 +753,11 @@
   this.pos = pos;
 }
 
-CallSite.prototype.__proto__ = null;
-
-CallSite.prototype.getThis = function () {
+function CallSiteGetThis() {
   return this.receiver;
 };
 
-CallSite.prototype.getTypeName = function () {
+function CallSiteGetTypeName() {
   var constructor = this.receiver.constructor;
   if (!constructor) {
     return %_CallFunction(this.receiver, ObjectToString);
@@ -739,33 +769,33 @@
   return constructorName;
 };
 
-CallSite.prototype.isToplevel = function () {
+function CallSiteIsToplevel() {
   if (this.receiver == null) {
     return true;
   }
   return IS_GLOBAL(this.receiver);
 };
 
-CallSite.prototype.isEval = function () {
+function CallSiteIsEval() {
   var script = %FunctionGetScript(this.fun);
   return script && script.compilation_type == COMPILATION_TYPE_EVAL;
 };
 
-CallSite.prototype.getEvalOrigin = function () {
+function CallSiteGetEvalOrigin() {
   var script = %FunctionGetScript(this.fun);
   return FormatEvalOrigin(script);
 };
 
-CallSite.prototype.getScriptNameOrSourceURL = function () {
+function CallSiteGetScriptNameOrSourceURL() {
   var script = %FunctionGetScript(this.fun);
   return script ? script.nameOrSourceURL() : null;
 };
 
-CallSite.prototype.getFunction = function () {
+function CallSiteGetFunction() {
   return this.fun;
 };
 
-CallSite.prototype.getFunctionName = function () {
+function CallSiteGetFunctionName() {
   // See if the function knows its own name
   var name = this.fun.name;
   if (name) {
@@ -781,7 +811,7 @@
   return null;
 };
 
-CallSite.prototype.getMethodName = function () {
+function CallSiteGetMethodName() {
   // See if we can find a unique property on the receiver that holds
   // this function.
   var ownName = this.fun.name;
@@ -811,12 +841,12 @@
   return null;
 };
 
-CallSite.prototype.getFileName = function () {
+function CallSiteGetFileName() {
   var script = %FunctionGetScript(this.fun);
   return script ? script.name : null;
 };
 
-CallSite.prototype.getLineNumber = function () {
+function CallSiteGetLineNumber() {
   if (this.pos == -1) {
     return null;
   }
@@ -828,7 +858,7 @@
   return location ? location.line + 1 : null;
 };
 
-CallSite.prototype.getColumnNumber = function () {
+function CallSiteGetColumnNumber() {
   if (this.pos == -1) {
     return null;
   }
@@ -840,16 +870,16 @@
   return location ? location.column + 1: null;
 };
 
-CallSite.prototype.isNative = function () {
+function CallSiteIsNative() {
   var script = %FunctionGetScript(this.fun);
   return script ? (script.type == TYPE_NATIVE) : false;
 };
 
-CallSite.prototype.getPosition = function () {
+function CallSiteGetPosition() {
   return this.pos;
 };
 
-CallSite.prototype.isConstructor = function () {
+function CallSiteIsConstructor() {
   var constructor = this.receiver ? this.receiver.constructor : null;
   if (!constructor) {
     return false;
@@ -857,6 +887,25 @@
   return this.fun === constructor;
 };
 
+SetUpLockedPrototype(CallSite, $Array("receiver", "fun", "pos"), $Array(
+  "getThis", CallSiteGetThis,
+  "getTypeName", CallSiteGetTypeName,
+  "isToplevel", CallSiteIsToplevel,
+  "isEval", CallSiteIsEval,
+  "getEvalOrigin", CallSiteGetEvalOrigin,
+  "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL,
+  "getFunction", CallSiteGetFunction,
+  "getFunctionName", CallSiteGetFunctionName,
+  "getMethodName", CallSiteGetMethodName,
+  "getFileName", CallSiteGetFileName,
+  "getLineNumber", CallSiteGetLineNumber,
+  "getColumnNumber", CallSiteGetColumnNumber,
+  "isNative", CallSiteIsNative,
+  "getPosition", CallSiteGetPosition,
+  "isConstructor", CallSiteIsConstructor
+));
+
+
 function FormatEvalOrigin(script) {
   var sourceURL = script.nameOrSourceURL();
   if (sourceURL) {
@@ -998,63 +1047,6 @@
   }
 }
 
-function DefineError(f) {
-  // Store the error function in both the global object
-  // and the runtime object. The function is fetched
-  // from the runtime object when throwing errors from
-  // within the runtime system to avoid strange side
-  // effects when overwriting the error functions from
-  // user code.
-  var name = f.name;
-  %SetProperty(global, name, f, DONT_ENUM);
-  this['$' + name] = f;
-  // Configure the error function.
-  if (name == 'Error') {
-    // The prototype of the Error object must itself be an error.
-    // However, it can't be an instance of the Error object because
-    // it hasn't been properly configured yet.  Instead we create a
-    // special not-a-true-error-but-close-enough object.
-    function ErrorPrototype() {}
-    %FunctionSetPrototype(ErrorPrototype, $Object.prototype);
-    %FunctionSetInstanceClassName(ErrorPrototype, 'Error');
-    %FunctionSetPrototype(f, new ErrorPrototype());
-  } else {
-    %FunctionSetPrototype(f, new $Error());
-  }
-  %FunctionSetInstanceClassName(f, 'Error');
-  %SetProperty(f.prototype, 'constructor', f, DONT_ENUM);
-  // The name property on the prototype of error objects is not
-  // specified as being read-one and dont-delete. However, allowing
-  // overwriting allows leaks of error objects between script blocks
-  // in the same context in a browser setting. Therefore we fix the
-  // name.
-  %SetProperty(f.prototype, "name", name, DONT_ENUM | DONT_DELETE | READ_ONLY);
-  %SetCode(f, function(m) {
-    if (%_IsConstructCall()) {
-      // Define all the expected properties directly on the error
-      // object. This avoids going through getters and setters defined
-      // on prototype objects.
-      %IgnoreAttributesAndSetProperty(this, 'stack', void 0, DONT_ENUM);
-      %IgnoreAttributesAndSetProperty(this, 'arguments', void 0, DONT_ENUM);
-      %IgnoreAttributesAndSetProperty(this, 'type', void 0, DONT_ENUM);
-      if (m === kAddMessageAccessorsMarker) {
-        // DefineOneShotAccessor always inserts a message property and
-        // ignores setters.
-        DefineOneShotAccessor(this, 'message', function (obj) {
-            return FormatMessage(%NewMessageObject(obj.type, obj.arguments));
-        });
-      } else if (!IS_UNDEFINED(m)) {
-        %IgnoreAttributesAndSetProperty(this,
-                                        'message',
-                                        ToString(m),
-                                        DONT_ENUM);
-      }
-      captureStackTrace(this, f);
-    } else {
-      return new f(m);
-    }
-  });
-}
 
 function captureStackTrace(obj, cons_opt) {
   var stackTraceLimit = $Error.stackTraceLimit;
@@ -1070,52 +1062,100 @@
   });
 };
 
-$Math.__proto__ = global.Object.prototype;
 
-// DefineError is a native function. Use explicit receiver. Otherwise
-// the receiver will be 'undefined'.
-this.DefineError(function Error() { });
-this.DefineError(function TypeError() { });
-this.DefineError(function RangeError() { });
-this.DefineError(function SyntaxError() { });
-this.DefineError(function ReferenceError() { });
-this.DefineError(function EvalError() { });
-this.DefineError(function URIError() { });
+function SetUpError() {
+  // Define special error type constructors.
+
+  function DefineError(f) {
+    // Store the error function in both the global object
+    // and the runtime object. The function is fetched
+    // from the runtime object when throwing errors from
+    // within the runtime system to avoid strange side
+    // effects when overwriting the error functions from
+    // user code.
+    var name = f.name;
+    %SetProperty(global, name, f, DONT_ENUM);
+    %SetProperty(builtins, '$' + name, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
+    // Configure the error function.
+    if (name == 'Error') {
+      // The prototype of the Error object must itself be an error.
+      // However, it can't be an instance of the Error object because
+      // it hasn't been properly configured yet.  Instead we create a
+      // special not-a-true-error-but-close-enough object.
+      function ErrorPrototype() {}
+      %FunctionSetPrototype(ErrorPrototype, $Object.prototype);
+      %FunctionSetInstanceClassName(ErrorPrototype, 'Error');
+      %FunctionSetPrototype(f, new ErrorPrototype());
+    } else {
+      %FunctionSetPrototype(f, new $Error());
+    }
+    %FunctionSetInstanceClassName(f, 'Error');
+    %SetProperty(f.prototype, 'constructor', f, DONT_ENUM);
+    // The name property on the prototype of error objects is not
+    // specified as being read-one and dont-delete. However, allowing
+    // overwriting allows leaks of error objects between script blocks
+    // in the same context in a browser setting. Therefore we fix the
+    // name.
+    %SetProperty(f.prototype, "name", name,
+                 DONT_ENUM | DONT_DELETE | READ_ONLY)  ;
+    %SetCode(f, function(m) {
+      if (%_IsConstructCall()) {
+        // Define all the expected properties directly on the error
+        // object. This avoids going through getters and setters defined
+        // on prototype objects.
+        %IgnoreAttributesAndSetProperty(this, 'stack', void 0, DONT_ENUM);
+        %IgnoreAttributesAndSetProperty(this, 'arguments', void 0, DONT_ENUM);
+        %IgnoreAttributesAndSetProperty(this, 'type', void 0, DONT_ENUM);
+        if (m === kAddMessageAccessorsMarker) {
+          // DefineOneShotAccessor always inserts a message property and
+          // ignores setters.
+          DefineOneShotAccessor(this, 'message', function (obj) {
+              return FormatMessage(%NewMessageObject(obj.type, obj.arguments));
+          });
+        } else if (!IS_UNDEFINED(m)) {
+          %IgnoreAttributesAndSetProperty(this,
+                                          'message',
+                                          ToString(m),
+                                          DONT_ENUM);
+        }
+        captureStackTrace(this, f);
+      } else {
+        return new f(m);
+      }
+    });
+  }
+
+  DefineError(function Error() { });
+  DefineError(function TypeError() { });
+  DefineError(function RangeError() { });
+  DefineError(function SyntaxError() { });
+  DefineError(function ReferenceError() { });
+  DefineError(function EvalError() { });
+  DefineError(function URIError() { });
+}
+
+SetUpError();
 
 $Error.captureStackTrace = captureStackTrace;
 
-// Setup extra properties of the Error.prototype object.
-function setErrorMessage() {
-  var desc = {value: '',
-              enumerable: false,
-              configurable: true,
-              writable: true };
-  DefineOwnProperty($Error.prototype,
-                    'message',
-                    ToPropertyDescriptor(desc),
-                    true);
-
-}
-
-setErrorMessage();
+%SetProperty($Error.prototype, 'message', '', DONT_ENUM);
 
 // Global list of error objects visited during errorToString. This is
 // used to detect cycles in error toString formatting.
-var visited_errors = new $Array();
-var cyclic_error_marker = new $Object();
+const visited_errors = new InternalArray();
+const cyclic_error_marker = new $Object();
 
-function errorToStringDetectCycle() {
-  if (!%PushIfAbsent(visited_errors, this)) throw cyclic_error_marker;
+function errorToStringDetectCycle(error) {
+  if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker;
   try {
-    var type = this.type;
-    if (type && !%_CallFunction(this, "message", ObjectHasOwnProperty)) {
-      var formatted = FormatMessage(%NewMessageObject(type, this.arguments));
-      return this.name + ": " + formatted;
+    var type = error.type;
+    var hasMessage = %_CallFunction(error, "message", ObjectHasOwnProperty);
+    if (type && !hasMessage) {
+      var formatted = FormatMessage(%NewMessageObject(type, error.arguments));
+      return error.name + ": " + formatted;
     }
-    var message = %_CallFunction(this, "message", ObjectHasOwnProperty)
-        ? (": " + this.message)
-        : "";
-    return this.name + message;
+    var message = hasMessage ? (": " + error.message) : "";
+    return error.name + message;
   } finally {
     visited_errors.length = visited_errors.length - 1;
   }
@@ -1131,7 +1171,7 @@
   function isCyclicErrorMarker(o) { return o === cyclic_error_marker; }
 
   try {
-    return %_CallFunction(this, errorToStringDetectCycle);
+    return errorToStringDetectCycle(this);
   } catch(e) {
     // If this error message was encountered already return the empty
     // string for it instead of recursively formatting it.
diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc
index 28ac557..f30f38b 100644
--- a/src/mips/assembler-mips.cc
+++ b/src/mips/assembler-mips.cc
@@ -49,11 +49,47 @@
 unsigned CpuFeatures::supported_ = 0;
 unsigned CpuFeatures::found_by_runtime_probing_ = 0;
 
+
+// Get the CPU features enabled by the build. For cross compilation the
+// preprocessor symbols CAN_USE_FPU_INSTRUCTIONS
+// can be defined to enable FPU instructions when building the
+// snapshot.
+static uint64_t CpuFeaturesImpliedByCompiler() {
+  uint64_t answer = 0;
+#ifdef CAN_USE_FPU_INSTRUCTIONS
+  answer |= 1u << FPU;
+#endif  // def CAN_USE_FPU_INSTRUCTIONS
+
+#ifdef __mips__
+  // If the compiler is allowed to use FPU then we can use FPU too in our code
+  // generation even when generating snapshots.  This won't work for cross
+  // compilation.
+#if(defined(__mips_hard_float) && __mips_hard_float != 0)
+  answer |= 1u << FPU;
+#endif  // defined(__mips_hard_float) && __mips_hard_float != 0
+#endif  // def __mips__
+
+  return answer;
+}
+
+
 void CpuFeatures::Probe() {
   ASSERT(!initialized_);
 #ifdef DEBUG
   initialized_ = true;
 #endif
+
+  // Get the features implied by the OS and the compiler settings. This is the
+  // minimal set of features which is also allowed for generated code in the
+  // snapshot.
+  supported_ |= OS::CpuFeaturesImpliedByPlatform();
+  supported_ |= CpuFeaturesImpliedByCompiler();
+
+  if (Serializer::enabled()) {
+    // No probing for features if we might serialize (generate snapshot).
+    return;
+  }
+
   // If the compiler is allowed to use fpu then we can use fpu too in our
   // code generation.
 #if !defined(__mips__)
@@ -62,11 +98,7 @@
       supported_ |= 1u << FPU;
   }
 #else
-  if (Serializer::enabled()) {
-    supported_ |= OS::CpuFeaturesImpliedByPlatform();
-    return;  // No features if we might serialize.
-  }
-
+  // Probe for additional features not already known to be available.
   if (OS::MipsCpuHasFeature(FPU)) {
     // This implementation also sets the FPU flags if
     // runtime detection of FPU returns true.
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index 1555653..d772304 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -210,7 +210,7 @@
   // Allocate the JSArray object together with space for a FixedArray with the
   // requested number of elements.
   __ bind(&not_empty);
-  ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
   __ li(elements_array_end,
         (JSArray::kSize + FixedArray::kHeaderSize) / kPointerSize);
   __ sra(scratch1, array_size, kSmiTagSize);
@@ -261,7 +261,7 @@
   // Length of the FixedArray is the number of pre-allocated elements if
   // the actual JSArray has length 0 and the size of the JSArray for non-empty
   // JSArrays. The length of a FixedArray is stored as a smi.
-  ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTag == 0);
   __ li(at, Operand(Smi::FromInt(JSArray::kPreallocatedArrayElements)));
   __ movz(array_size, at, array_size);
 
@@ -273,7 +273,7 @@
   // result: JSObject
   // elements_array_storage: elements array element storage
   // array_size: smi-tagged size of elements array
-  ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
+  STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
   __ sll(elements_array_end, array_size, kPointerSizeLog2 - kSmiTagSize);
   __ Addu(elements_array_end, elements_array_storage, elements_array_end);
 
@@ -336,14 +336,14 @@
   __ bind(&argc_one_or_more);
   __ Branch(&argc_two_or_more, ne, a0, Operand(1));
 
-  ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTag == 0);
   __ lw(a2, MemOperand(sp));  // Get the argument from the stack.
   __ And(a3, a2, Operand(kIntptrSignBit | kSmiTagMask));
   __ Branch(call_generic_code, eq, a3, Operand(zero_reg));
 
   // Handle construction of an empty array of a certain size. Bail out if size
   // is too large to actually allocate an elements array.
-  ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTag == 0);
   __ Branch(call_generic_code, Ugreater_equal, a2,
             Operand(JSObject::kInitialMaxFastElementArray << kSmiTagSize));
 
@@ -576,7 +576,7 @@
   // Is it a String?
   __ lw(a2, FieldMemOperand(a0, HeapObject::kMapOffset));
   __ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset));
-  ASSERT(kNotStringTag != 0);
+  STATIC_ASSERT(kNotStringTag != 0);
   __ And(t0, a3, Operand(kIsNotStringMask));
   __ Branch(&convert_argument, ne, t0, Operand(zero_reg));
   __ mov(argument, a0);
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 9385f2f..ef0bf77 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -3538,7 +3538,7 @@
     const int kNumInstructionsToJump = 6;
     masm->Addu(ra, ra, kNumInstructionsToJump * kPointerSize);
     masm->sw(ra, MemOperand(sp));  // This spot was reserved in EnterExitFrame.
-    masm->Subu(sp, sp, StandardFrameConstants::kCArgsSlotsSize);
+    masm->Subu(sp, sp, kCArgsSlotsSize);
     // Stack is still aligned.
 
     // Call the C routine.
@@ -3551,7 +3551,7 @@
   }
 
   // Restore stack (remove arg slots).
-  __ Addu(sp, sp, StandardFrameConstants::kCArgsSlotsSize);
+  __ Addu(sp, sp, kCArgsSlotsSize);
 
   if (always_allocate) {
     // It's okay to clobber a2 and a3 here. v0 & v1 contain result.
@@ -3695,9 +3695,19 @@
   // Save callee saved registers on the stack.
   __ MultiPush(kCalleeSaved | ra.bit());
 
+  if (CpuFeatures::IsSupported(FPU)) {
+    CpuFeatures::Scope scope(FPU);
+    // Save callee-saved FPU registers.
+    __ MultiPushFPU(kCalleeSavedFPU);
+  }
+
   // Load argv in s0 register.
-  __ lw(s0, MemOperand(sp, (kNumCalleeSaved + 1) * kPointerSize +
-                           StandardFrameConstants::kCArgsSlotsSize));
+  int offset_to_argv = (kNumCalleeSaved + 1) * kPointerSize;
+  if (CpuFeatures::IsSupported(FPU)) {
+    offset_to_argv += kNumCalleeSavedFPU * kDoubleSize;
+  }
+
+  __ lw(s0, MemOperand(sp, offset_to_argv + kCArgsSlotsSize));
 
   // We build an EntryFrame.
   __ li(t3, Operand(-1));  // Push a bad frame pointer to fail if it is used.
@@ -3829,6 +3839,12 @@
   // Reset the stack to the callee saved registers.
   __ addiu(sp, sp, -EntryFrameConstants::kCallerFPOffset);
 
+  if (CpuFeatures::IsSupported(FPU)) {
+    CpuFeatures::Scope scope(FPU);
+    // Restore callee-saved fpu registers.
+    __ MultiPopFPU(kCalleeSavedFPU);
+  }
+
   // Restore callee saved registers from the stack.
   __ MultiPop(kCalleeSaved | ra.bit());
   // Return.
@@ -5062,7 +5078,8 @@
 
   // Check for 1-byte or 2-byte string.
   __ bind(&flat_string);
-  STATIC_ASSERT(kAsciiStringTag != 0);
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
   __ And(t0, result_, Operand(kStringEncodingMask));
   __ Branch(&ascii_string, ne, t0, Operand(zero_reg));
 
@@ -5625,11 +5642,6 @@
   Register to = t2;
   Register from = t3;
 
-  if (FLAG_string_slices) {
-    __ nop();  // Jumping as first instruction would crash the code generation.
-    __ jmp(&sub_string_runtime);
-  }
-
   // Check bounds and smi-ness.
   __ lw(to, MemOperand(sp, kToOffset));
   __ lw(from, MemOperand(sp, kFromOffset));
@@ -5653,7 +5665,8 @@
 
   // Special handling of sub-strings of length 1 and 2. One character strings
   // are handled in the runtime system (looked up in the single character
-  // cache). Two character strings are looked for in the symbol cache.
+  // cache). Two character strings are looked for in the symbol cache in
+  // generated code.
   __ Branch(&sub_string_runtime, lt, a2, Operand(2));
 
   // Both to and from are smis.
@@ -5665,19 +5678,32 @@
   // t5: to index (untagged smi)
 
   // Make sure first argument is a sequential (or flat) string.
-  __ lw(t1, MemOperand(sp, kStringOffset));
-  __ Branch(&sub_string_runtime, eq, t1, Operand(kSmiTagMask));
+  __ lw(v0, MemOperand(sp, kStringOffset));
+  __ Branch(&sub_string_runtime, eq, v0, Operand(kSmiTagMask));
 
-  __ lw(a1, FieldMemOperand(t1, HeapObject::kMapOffset));
+  __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
   __ lbu(a1, FieldMemOperand(a1, Map::kInstanceTypeOffset));
-  __ And(t4, a1, Operand(kIsNotStringMask));
+  __ And(t4, v0, Operand(kIsNotStringMask));
 
   __ Branch(&sub_string_runtime, ne, t4, Operand(zero_reg));
 
+  // Short-cut for the case of trivial substring.
+  Label return_v0;
+  // v0: original string
+  // a2: result string length
+  __ lw(t0, FieldMemOperand(v0, String::kLengthOffset));
+  __ sra(t0, t0, 1);
+  __ Branch(&return_v0, eq, a2, Operand(t0));
+
+  Label create_slice;
+  if (FLAG_string_slices) {
+    __ Branch(&create_slice, ge, a2, Operand(SlicedString::kMinLength));
+  }
+
+  // v0: original string
   // a1: instance type
   // a2: result string length
   // a3: from index (untagged smi)
-  // t1: string
   // t2: (a.k.a. to): to (smi)
   // t3: (a.k.a. from): from offset (smi)
   // t5: to index (untagged smi)
@@ -5686,8 +5712,9 @@
   __ And(t0, a1, Operand(kStringRepresentationMask));
   STATIC_ASSERT(kSeqStringTag < kConsStringTag);
   STATIC_ASSERT(kConsStringTag < kExternalStringTag);
+  STATIC_ASSERT(kConsStringTag < kSlicedStringTag);
 
-  // External strings go to runtime.
+  // Slices and external strings go to runtime.
   __ Branch(&sub_string_runtime, gt, t0, Operand(kConsStringTag));
 
   // Sequential strings are handled directly.
@@ -5696,32 +5723,32 @@
   // Cons string. Try to recurse (once) on the first substring.
   // (This adds a little more generality than necessary to handle flattened
   // cons strings, but not much).
-  __ lw(t1, FieldMemOperand(t1, ConsString::kFirstOffset));
-  __ lw(t0, FieldMemOperand(t1, HeapObject::kMapOffset));
+  __ lw(v0, FieldMemOperand(v0, ConsString::kFirstOffset));
+  __ lw(t0, FieldMemOperand(v0, HeapObject::kMapOffset));
   __ lbu(a1, FieldMemOperand(t0, Map::kInstanceTypeOffset));
   STATIC_ASSERT(kSeqStringTag == 0);
-  // Cons and External strings go to runtime.
+  // Cons, slices and external strings go to runtime.
   __ Branch(&sub_string_runtime, ne, a1, Operand(kStringRepresentationMask));
 
   // Definitly a sequential string.
   __ bind(&seq_string);
 
+  // v0: original string
   // a1: instance type
   // a2: result string length
   // a3: from index (untagged smi)
-  // t1: string
   // t2: (a.k.a. to): to (smi)
   // t3: (a.k.a. from): from offset (smi)
   // t5: to index (untagged smi)
 
-  __ lw(t0, FieldMemOperand(t1, String::kLengthOffset));
+  __ lw(t0, FieldMemOperand(v0, String::kLengthOffset));
   __ Branch(&sub_string_runtime, lt, t0, Operand(to));  // Fail if to > length.
   to = no_reg;
 
+  // v0: original string or left hand side of the original cons string.
   // a1: instance type
   // a2: result string length
   // a3: from index (untagged smi)
-  // t1: string
   // t3: (a.k.a. from): from offset (smi)
   // t5: to index (untagged smi)
 
@@ -5737,84 +5764,147 @@
 
   // Sub string of length 2 requested.
   // Get the two characters forming the sub string.
-  __ Addu(t1, t1, Operand(a3));
-  __ lbu(a3, FieldMemOperand(t1, SeqAsciiString::kHeaderSize));
-  __ lbu(t0, FieldMemOperand(t1, SeqAsciiString::kHeaderSize + 1));
+  __ Addu(v0, v0, Operand(a3));
+  __ lbu(a3, FieldMemOperand(v0, SeqAsciiString::kHeaderSize));
+  __ lbu(t0, FieldMemOperand(v0, SeqAsciiString::kHeaderSize + 1));
 
   // Try to lookup two character string in symbol table.
   Label make_two_character_string;
   StringHelper::GenerateTwoCharacterSymbolTableProbe(
       masm, a3, t0, a1, t1, t2, t3, t4, &make_two_character_string);
   Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->sub_string_native(), 1, a3, t0);
-  __ Addu(sp, sp, Operand(3 * kPointerSize));
-  __ Ret();
-
+  __ jmp(&return_v0);
 
   // a2: result string length.
   // a3: two characters combined into halfword in little endian byte order.
   __ bind(&make_two_character_string);
   __ AllocateAsciiString(v0, a2, t0, t1, t4, &sub_string_runtime);
   __ sh(a3, FieldMemOperand(v0, SeqAsciiString::kHeaderSize));
-  __ IncrementCounter(counters->sub_string_native(), 1, a3, t0);
-  __ Addu(sp, sp, Operand(3 * kPointerSize));
-  __ Ret();
+  __ jmp(&return_v0);
 
   __ bind(&result_longer_than_two);
 
+  // Locate 'from' character of string.
+  __ Addu(t1, v0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
+  __ sra(t4, from, 1);
+  __ Addu(t1, t1, t4);
+
   // Allocate the result.
   __ AllocateAsciiString(v0, a2, t4, t0, a1, &sub_string_runtime);
 
-  // v0: result string.
-  // a2: result string length.
+  // v0: result string
+  // a2: result string length
   // a3: from index (untagged smi)
-  // t1: string.
+  // t1: first character of substring to copy
   // t3: (a.k.a. from): from offset (smi)
   // Locate first character of result.
   __ Addu(a1, v0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
-  // Locate 'from' character of string.
-  __ Addu(t1, t1, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
-  __ Addu(t1, t1, Operand(a3));
 
-  // v0: result string.
-  // a1: first character of result string.
-  // a2: result string length.
-  // t1: first character of sub string to copy.
+  // v0: result string
+  // a1: first character of result string
+  // a2: result string length
+  // t1: first character of substring to copy
   STATIC_ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0);
   StringHelper::GenerateCopyCharactersLong(
       masm, a1, t1, a2, a3, t0, t2, t3, t4, COPY_ASCII | DEST_ALWAYS_ALIGNED);
-  __ IncrementCounter(counters->sub_string_native(), 1, a3, t0);
-  __ Addu(sp, sp, Operand(3 * kPointerSize));
-  __ Ret();
+  __ jmp(&return_v0);
 
   __ bind(&non_ascii_flat);
-  // a2: result string length.
-  // t1: string.
+  // a2: result string length
+  // t1: string
   // t3: (a.k.a. from): from offset (smi)
   // Check for flat two byte string.
 
+  // Locate 'from' character of string.
+  __ Addu(t1, v0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
+  // As "from" is a smi it is 2 times the value which matches the size of a two
+  // byte character.
+  STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
+  __ Addu(t1, t1, Operand(from));
+
   // Allocate the result.
   __ AllocateTwoByteString(v0, a2, a1, a3, t0, &sub_string_runtime);
 
-  // v0: result string.
-  // a2: result string length.
-  // t1: string.
+  // v0: result string
+  // a2: result string length
+  // t1: first character of substring to copy
   // Locate first character of result.
   __ Addu(a1, v0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
-  // Locate 'from' character of string.
-  __ Addu(t1, t1, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
-  // As "from" is a smi it is 2 times the value which matches the size of a two
-  // byte character.
-  __ Addu(t1, t1, Operand(from));
+
   from = no_reg;
 
   // v0: result string.
   // a1: first character of result.
   // a2: result length.
-  // t1: first character of string to copy.
+  // t1: first character of substring to copy.
   STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
   StringHelper::GenerateCopyCharactersLong(
       masm, a1, t1, a2, a3, t0, t2, t3, t4, DEST_ALWAYS_ALIGNED);
+  __ jmp(&return_v0);
+
+  if (FLAG_string_slices) {
+    __ bind(&create_slice);
+    // v0: original string
+    // a1: instance type
+    // a2: length
+    // a3: from index (untagged smi)
+    // t2 (a.k.a. to): to (smi)
+    // t3 (a.k.a. from): from offset (smi)
+    Label allocate_slice, sliced_string, seq_string;
+    STATIC_ASSERT(kSeqStringTag == 0);
+    __ And(t4, a1, Operand(kStringRepresentationMask));
+    __ Branch(&seq_string, eq, t4, Operand(zero_reg));
+    STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
+    STATIC_ASSERT(kIsIndirectStringMask != 0);
+    __ And(t4, a1, Operand(kIsIndirectStringMask));
+    // External string.  Jump to runtime.
+    __ Branch(&sub_string_runtime, eq, t4, Operand(zero_reg));
+
+    __ And(t4, a1, Operand(kSlicedNotConsMask));
+    __ Branch(&sliced_string, ne, t4, Operand(zero_reg));
+    // Cons string.  Check whether it is flat, then fetch first part.
+    __ lw(t1, FieldMemOperand(v0, ConsString::kSecondOffset));
+    __ LoadRoot(t5, Heap::kEmptyStringRootIndex);
+    __ Branch(&sub_string_runtime, ne, t1, Operand(t5));
+    __ lw(t1, FieldMemOperand(v0, ConsString::kFirstOffset));
+    __ jmp(&allocate_slice);
+
+    __ bind(&sliced_string);
+    // Sliced string.  Fetch parent and correct start index by offset.
+    __ lw(t1, FieldMemOperand(v0, SlicedString::kOffsetOffset));
+    __ addu(t3, t3, t1);
+    __ lw(t1, FieldMemOperand(v0, SlicedString::kParentOffset));
+    __ jmp(&allocate_slice);
+
+    __ bind(&seq_string);
+    // Sequential string.  Just move string to the right register.
+    __ mov(t1, v0);
+
+    __ bind(&allocate_slice);
+    // a1: instance type of original string
+    // a2: length
+    // t1: underlying subject string
+    // t3 (a.k.a. from): from offset (smi)
+    // Allocate new sliced string.  At this point we do not reload the instance
+    // type including the string encoding because we simply rely on the info
+    // provided by the original string.  It does not matter if the original
+    // string's encoding is wrong because we always have to recheck encoding of
+    // the newly created string's parent anyways due to externalized strings.
+    Label two_byte_slice, set_slice_header;
+    STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+    STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
+    __ And(t4, a1, Operand(kStringEncodingMask));
+    __ Branch(&two_byte_slice, eq, t4, Operand(zero_reg));
+    __ AllocateAsciiSlicedString(v0, a2, a3, t0, &sub_string_runtime);
+    __ jmp(&set_slice_header);
+    __ bind(&two_byte_slice);
+    __ AllocateTwoByteSlicedString(v0, a2, a3, t0, &sub_string_runtime);
+    __ bind(&set_slice_header);
+    __ sw(t3, FieldMemOperand(v0, SlicedString::kOffsetOffset));
+    __ sw(t1, FieldMemOperand(v0, SlicedString::kParentOffset));
+  }
+
+  __ bind(&return_v0);
   __ IncrementCounter(counters->sub_string_native(), 1, a3, t0);
   __ Addu(sp, sp, Operand(3 * kPointerSize));
   __ Ret();
diff --git a/src/mips/constants-mips.h b/src/mips/constants-mips.h
index 6bf2570..ede9688 100644
--- a/src/mips/constants-mips.h
+++ b/src/mips/constants-mips.h
@@ -743,11 +743,9 @@
 // -----------------------------------------------------------------------------
 // MIPS assembly various constants.
 
-
-static const int kArgsSlotsSize  = 4 * Instruction::kInstrSize;
-static const int kArgsSlotsNum   = 4;
 // C/C++ argument slots size.
-static const int kCArgsSlotsSize = 4 * Instruction::kInstrSize;
+static const int kCArgSlotCount = 4;
+static const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize;
 // JS argument slots size.
 static const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize;
 // Assembly builtins argument slots size.
diff --git a/src/mips/frames-mips.h b/src/mips/frames-mips.h
index 1899843..798ef23 100644
--- a/src/mips/frames-mips.h
+++ b/src/mips/frames-mips.h
@@ -30,7 +30,6 @@
 #ifndef V8_MIPS_FRAMES_MIPS_H_
 #define V8_MIPS_FRAMES_MIPS_H_
 
-
 namespace v8 {
 namespace internal {
 
@@ -40,13 +39,22 @@
 static const int kNumRegs = 32;
 
 static const RegList kJSCallerSaved =
-  1 << 2 |  // v0
-  1 << 4 |  // a0
-  1 << 5 |  // a1
-  1 << 6 |  // a2
-  1 << 7;   // a3
+  1 << 2  |  // v0
+  1 << 3  |  // v1
+  1 << 4  |  // a0
+  1 << 5  |  // a1
+  1 << 6  |  // a2
+  1 << 7  |  // a3
+  1 << 8  |  // t0
+  1 << 9  |  // t1
+  1 << 10 |  // t2
+  1 << 11 |  // t3
+  1 << 12 |  // t4
+  1 << 13 |  // t5
+  1 << 14 |  // t6
+  1 << 15;   // t7
 
-static const int kNumJSCallerSaved = 5;
+static const int kNumJSCallerSaved = 14;
 
 
 // Return the code of the n-th caller-saved register available to JavaScript
@@ -56,19 +64,31 @@
 
 // Callee-saved registers preserved when switching from C to JavaScript.
 static const RegList kCalleeSaved =
-  // Saved temporaries.
-  1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 |
-  1 << 20 | 1 << 21 | 1 << 22 | 1 << 23 |
-  // fp.
-  1 << 30;
+  1 << 16 |  // s0
+  1 << 17 |  // s1
+  1 << 18 |  // s2
+  1 << 19 |  // s3
+  1 << 20 |  // s4
+  1 << 21 |  // s5
+  1 << 22 |  // s6 (roots in Javascript code)
+  1 << 23 |  // s7 (cp in Javascript code)
+  1 << 30;   // fp/s8
 
 static const int kNumCalleeSaved = 9;
 
+static const RegList kCalleeSavedFPU =
+  1 << 20 |  // f20
+  1 << 22 |  // f22
+  1 << 24 |  // f24
+  1 << 26 |  // f26
+  1 << 28 |  // f28
+  1 << 30;   // f30
 
+static const int kNumCalleeSavedFPU = 6;
 // Number of registers for which space is reserved in safepoints. Must be a
 // multiple of 8.
 // TODO(mips): Only 8 registers may actually be sufficient. Revisit.
-static const int kNumSafepointRegisters = 16;
+static const int kNumSafepointRegisters = 24;
 
 // Define the list of registers actually saved at safepoints.
 // Note that the number of saved registers may be smaller than the reserved
@@ -82,37 +102,37 @@
 static const int kUndefIndex = -1;
 // Map with indexes on stack that corresponds to codes of saved registers.
 static const int kSafepointRegisterStackIndexMap[kNumRegs] = {
-  kUndefIndex,
-  kUndefIndex,
-  0,  // v0
-  kUndefIndex,
-  1,  // a0
-  2,  // a1
-  3,  // a2
-  4,  // a3
-  kUndefIndex,
-  kUndefIndex,
-  kUndefIndex,
-  kUndefIndex,
-  kUndefIndex,
-  kUndefIndex,
-  kUndefIndex,
-  kUndefIndex,
-  5,  // Saved temporaries.
-  6,
-  7,
-  8,
-  9,
-  10,
-  11,
-  12,
-  kUndefIndex,
-  kUndefIndex,
-  kUndefIndex,
-  kUndefIndex,
-  13,  // gp
-  14,  // sp
-  15,  // fp
+  kUndefIndex,  // zero_reg
+  kUndefIndex,  // at
+  0,   // v0
+  1,   // v1
+  2,   // a0
+  3,   // a1
+  4,   // a2
+  5,   // a3
+  6,   // t0
+  7,   // t1
+  8,   // t2
+  9,   // t3
+  10,  // t4
+  11,  // t5
+  12,  // t6
+  13,  // t7
+  14,  // s0
+  15,  // s1
+  16,  // s2
+  17,  // s3
+  18,  // s4
+  19,  // s5
+  20,  // s6
+  21,  // s7
+  kUndefIndex,  // t8
+  kUndefIndex,  // t9
+  kUndefIndex,  // k0
+  kUndefIndex,  // k1
+  kUndefIndex,  // gp
+  kUndefIndex,  // sp
+  22,  // fp
   kUndefIndex
 };
 
@@ -174,9 +194,6 @@
   static const int kRArgsSlotsSize = 4 * kPointerSize;
   static const int kRegularArgsSlotsSize = kRArgsSlotsSize;
 
-  // C/C++ argument slots size.
-  static const int kCArgSlotCount = 4;
-  static const int kCArgsSlotsSize = kCArgSlotCount * kPointerSize;
   // JS argument slots size.
   static const int kJSArgsSlotsSize = 0 * kPointerSize;
   // Assembly builtins argument slots size.
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 3c0c316..48c176a 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -266,6 +266,7 @@
     scope()->VisitIllegalRedeclaration(this);
 
   } else {
+    PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
     { Comment cmnt(masm_, "[ Declarations");
       // For named function expressions, declare the function name as a
       // constant.
@@ -276,7 +277,7 @@
     }
 
     { Comment cmnt(masm_, "[ Stack check");
-      PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
+      PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
       Label ok;
       __ LoadRoot(t0, Heap::kStackLimitRootIndex);
       __ Branch(&ok, hs, sp, Operand(t0));
@@ -700,12 +701,12 @@
   switch (slot->type()) {
     case Slot::PARAMETER:
     case Slot::LOCAL:
-      if (mode == Variable::CONST) {
-        __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
-        __ sw(t0, MemOperand(fp, SlotOffset(slot)));
-      } else if (function != NULL) {
+      if (function != NULL) {
         VisitForAccumulatorValue(function);
         __ sw(result_register(), MemOperand(fp, SlotOffset(slot)));
+      } else if (mode == Variable::CONST || mode == Variable::LET) {
+          __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
+          __ sw(t0, MemOperand(fp, SlotOffset(slot)));
       }
       break;
 
@@ -726,17 +727,17 @@
         __ Check(ne, "Declaration in catch context.",
                  a1, Operand(t0));
       }
-      if (mode == Variable::CONST) {
-        __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
-        __ sw(at, ContextOperand(cp, slot->index()));
-        // No write barrier since the_hole_value is in old space.
-      } else if (function != NULL) {
+      if (function != NULL) {
         VisitForAccumulatorValue(function);
         __ sw(result_register(), ContextOperand(cp, slot->index()));
         int offset = Context::SlotOffset(slot->index());
         // We know that we have written a function, which is not a smi.
         __ mov(a1, cp);
         __ RecordWrite(a1, Operand(offset), a2, result_register());
+      } else if (mode == Variable::CONST || mode == Variable::LET) {
+          __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
+          __ sw(at, ContextOperand(cp, slot->index()));
+          // No write barrier since the_hole_value is in old space.
       }
       break;
 
@@ -752,13 +753,13 @@
       // Note: For variables we must not push an initial value (such as
       // 'undefined') because we may have a (legal) redeclaration and we
       // must not destroy the current value.
-      if (mode == Variable::CONST) {
-        __ LoadRoot(a0, Heap::kTheHoleValueRootIndex);
-        __ Push(cp, a2, a1, a0);
-      } else if (function != NULL) {
+      if (function != NULL) {
         __ Push(cp, a2, a1);
         // Push initial value for function declaration.
         VisitForStackValue(function);
+      } else if (mode == Variable::CONST || mode == Variable::LET) {
+          __ LoadRoot(a0, Heap::kTheHoleValueRootIndex);
+          __ Push(cp, a2, a1, a0);
       } else {
         ASSERT(Smi::FromInt(0) == 0);
         // No initial value!
@@ -780,11 +781,10 @@
 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
   // Call the runtime to declare the globals.
   // The context is the first argument.
-  __ li(a2, Operand(pairs));
-  __ li(a1, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
-  __ li(a0, Operand(Smi::FromInt(strict_mode_flag())));
-  __ Push(cp, a2, a1, a0);
-  __ CallRuntime(Runtime::kDeclareGlobals, 4);
+  __ li(a1, Operand(pairs));
+  __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
+  __ Push(cp, a1, a0);
+  __ CallRuntime(Runtime::kDeclareGlobals, 3);
   // Return value is ignored.
 }
 
@@ -1279,9 +1279,22 @@
        __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
        __ movz(v0, a0, at);  // Conditional move.
        context()->Plug(v0);
-     } else {
-       context()->Plug(slot);
-     }
+    } else if (var->mode() == Variable::LET) {
+      // Let bindings may be the hole value if they have not been initialized.
+      // Throw a type error in this case.
+      Label done;
+      MemOperand slot_operand = EmitSlotSearch(slot, a0);
+      __ lw(v0, slot_operand);
+      __ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
+      __ Branch(&done, ne, v0, Operand(a1));
+      __ li(v0, Operand(var->name()));
+      __ push(v0);
+      __ CallRuntime(Runtime::kThrowReferenceError, 1);
+      __ bind(&done);
+      context()->Plug(v0);
+    } else {
+      context()->Plug(slot);
+    }
   }
 }
 
@@ -1863,6 +1876,56 @@
         break;
     }
     __ bind(&skip);
+  } else if (var->mode() == Variable::LET && op != Token::INIT_LET) {
+    // Perform the assignment for non-const variables.  Const assignments
+    // are simply skipped.
+    Slot* slot = var->AsSlot();
+    switch (slot->type()) {
+      case Slot::PARAMETER:
+      case Slot::LOCAL: {
+        Label assign;
+        // Check for an initialized let binding.
+        __ lw(a1, MemOperand(fp, SlotOffset(slot)));
+        __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
+        __ Branch(&assign, ne, a1, Operand(t0));
+        __ li(a1, Operand(var->name()));
+        __ push(a1);
+        __ CallRuntime(Runtime::kThrowReferenceError, 1);
+        // Perform the assignment.
+        __ bind(&assign);
+        __ sw(result_register(), MemOperand(fp, SlotOffset(slot)));
+        break;
+      }
+      case Slot::CONTEXT: {
+        // Let variables may be the hole value if they have not been
+        // initialized. Throw a type error in this case.
+        Label assign;
+        MemOperand target = EmitSlotSearch(slot, a1);
+        // Check for an initialized let binding.
+        __ lw(a3, target);
+        __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
+        __ Branch(&assign, ne, a3, Operand(t0));
+        __ li(a3, Operand(var->name()));
+        __ push(a3);
+        __ CallRuntime(Runtime::kThrowReferenceError, 1);
+        // Perform the assignment.
+        __ bind(&assign);
+        __ sw(result_register(), target);
+        // RecordWrite may destroy all its register arguments.
+        __ mov(a3, result_register());
+        int offset = Context::SlotOffset(slot->index());
+        __ RecordWrite(a1, Operand(offset), a2, a3);
+        break;
+      }
+      case Slot::LOOKUP:
+        // Call the runtime for the assignment.
+        __ push(v0);  // Value.
+        __ li(a1, Operand(slot->var()->name()));
+        __ li(a0, Operand(Smi::FromInt(strict_mode_flag())));
+        __ Push(cp, a1, a0);  // Context, name, strict mode.
+        __ CallRuntime(Runtime::kStoreContextSlot, 4);
+        break;
+    }
 
   } else if (var->mode() != Variable::CONST) {
     // Perform the assignment for non-const variables.  Const assignments
@@ -2113,8 +2176,13 @@
   int receiver_offset = 2 + info_->scope()->num_parameters();
   __ lw(a1, MemOperand(fp, receiver_offset * kPointerSize));
   __ push(a1);
-  // Push the strict mode flag.
-  __ li(a1, Operand(Smi::FromInt(strict_mode_flag())));
+  // Push the strict mode flag. In harmony mode every eval call
+  // is a strict mode eval call.
+  StrictModeFlag strict_mode = strict_mode_flag();
+  if (FLAG_harmony_block_scoping) {
+    strict_mode = kStrictMode;
+  }
+  __ li(a1, Operand(Smi::FromInt(strict_mode)));
   __ push(a1);
 
   __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
@@ -3206,7 +3274,7 @@
 
 
   Label done, not_found;
-  ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
+  STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
   __ lw(a2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset));
   // a2 now holds finger offset as a smi.
   __ Addu(a3, cache, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
@@ -4201,7 +4269,7 @@
   // Cook return address in link register to stack (smi encoded Code* delta).
   __ Subu(a1, ra, Operand(masm_->CodeObject()));
   ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
-  ASSERT_EQ(0, kSmiTag);
+  STATIC_ASSERT(0 == kSmiTag);
   __ Addu(a1, a1, Operand(a1));  // Convert to smi.
   __ push(a1);
 }
diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc
index 85cb916..5ef3554 100644
--- a/src/mips/ic-mips.cc
+++ b/src/mips/ic-mips.cc
@@ -338,7 +338,7 @@
   __ Addu(scratch1, elements,
           Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   // The key is a smi.
-  ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
+  STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
   __ sll(at, key, kPointerSizeLog2 - kSmiTagSize);
   __ addu(at, at, scratch1);
   __ lw(scratch2, MemOperand(at));
@@ -372,7 +372,7 @@
   // Is the string a symbol?
   // map: key map
   __ lbu(hash, FieldMemOperand(map, Map::kInstanceTypeOffset));
-  ASSERT(kSymbolTag != 0);
+  STATIC_ASSERT(kSymbolTag != 0);
   __ And(at, hash, Operand(kIsSymbolMask));
   __ Branch(not_symbol, eq, at, Operand(zero_reg));
 }
@@ -1269,7 +1269,7 @@
   __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
   __ Branch(&slow, hs, key, Operand(t0));
   // Calculate key + 1 as smi.
-  ASSERT_EQ(0, kSmiTag);
+  STATIC_ASSERT(0 == kSmiTag);
   __ Addu(t3, key, Operand(Smi::FromInt(1)));
   __ sw(t3, FieldMemOperand(receiver, JSArray::kLengthOffset));
   __ Branch(&fast);
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index c7f727b..1a37d65 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -703,52 +703,114 @@
 
 
 void MacroAssembler::MultiPush(RegList regs) {
-  int16_t NumSaved = 0;
-  int16_t NumToPush = NumberOfBitsSet(regs);
+  int16_t num_to_push = NumberOfBitsSet(regs);
+  int16_t stack_offset = num_to_push * kPointerSize;
 
-  addiu(sp, sp, -4 * NumToPush);
+  Subu(sp, sp, Operand(stack_offset));
   for (int16_t i = kNumRegisters; i > 0; i--) {
     if ((regs & (1 << i)) != 0) {
-      sw(ToRegister(i), MemOperand(sp, 4 * (NumToPush - ++NumSaved)));
+      stack_offset -= kPointerSize;
+      sw(ToRegister(i), MemOperand(sp, stack_offset));
     }
   }
 }
 
 
 void MacroAssembler::MultiPushReversed(RegList regs) {
-  int16_t NumSaved = 0;
-  int16_t NumToPush = NumberOfBitsSet(regs);
+  int16_t num_to_push = NumberOfBitsSet(regs);
+  int16_t stack_offset = num_to_push * kPointerSize;
 
-  addiu(sp, sp, -4 * NumToPush);
+  Subu(sp, sp, Operand(stack_offset));
   for (int16_t i = 0; i < kNumRegisters; i++) {
     if ((regs & (1 << i)) != 0) {
-      sw(ToRegister(i), MemOperand(sp, 4 * (NumToPush - ++NumSaved)));
+      stack_offset -= kPointerSize;
+      sw(ToRegister(i), MemOperand(sp, stack_offset));
     }
   }
 }
 
 
 void MacroAssembler::MultiPop(RegList regs) {
-  int16_t NumSaved = 0;
+  int16_t stack_offset = 0;
 
   for (int16_t i = 0; i < kNumRegisters; i++) {
     if ((regs & (1 << i)) != 0) {
-      lw(ToRegister(i), MemOperand(sp, 4 * (NumSaved++)));
+      lw(ToRegister(i), MemOperand(sp, stack_offset));
+      stack_offset += kPointerSize;
     }
   }
-  addiu(sp, sp, 4 * NumSaved);
+  addiu(sp, sp, stack_offset);
 }
 
 
 void MacroAssembler::MultiPopReversed(RegList regs) {
-  int16_t NumSaved = 0;
+  int16_t stack_offset = 0;
 
   for (int16_t i = kNumRegisters; i > 0; i--) {
     if ((regs & (1 << i)) != 0) {
-      lw(ToRegister(i), MemOperand(sp, 4 * (NumSaved++)));
+      lw(ToRegister(i), MemOperand(sp, stack_offset));
+      stack_offset += kPointerSize;
     }
   }
-  addiu(sp, sp, 4 * NumSaved);
+  addiu(sp, sp, stack_offset);
+}
+
+
+void MacroAssembler::MultiPushFPU(RegList regs) {
+  CpuFeatures::Scope scope(FPU);
+  int16_t num_to_push = NumberOfBitsSet(regs);
+  int16_t stack_offset = num_to_push * kDoubleSize;
+
+  Subu(sp, sp, Operand(stack_offset));
+  for (int16_t i = kNumRegisters; i > 0; i--) {
+    if ((regs & (1 << i)) != 0) {
+      stack_offset -= kDoubleSize;
+      sdc1(FPURegister::from_code(i), MemOperand(sp, stack_offset));
+    }
+  }
+}
+
+
+void MacroAssembler::MultiPushReversedFPU(RegList regs) {
+  CpuFeatures::Scope scope(FPU);
+  int16_t num_to_push = NumberOfBitsSet(regs);
+  int16_t stack_offset = num_to_push * kDoubleSize;
+
+  Subu(sp, sp, Operand(stack_offset));
+  for (int16_t i = 0; i < kNumRegisters; i++) {
+    if ((regs & (1 << i)) != 0) {
+      stack_offset -= kDoubleSize;
+      sdc1(FPURegister::from_code(i), MemOperand(sp, stack_offset));
+    }
+  }
+}
+
+
+void MacroAssembler::MultiPopFPU(RegList regs) {
+  CpuFeatures::Scope scope(FPU);
+  int16_t stack_offset = 0;
+
+  for (int16_t i = 0; i < kNumRegisters; i++) {
+    if ((regs & (1 << i)) != 0) {
+      ldc1(FPURegister::from_code(i), MemOperand(sp, stack_offset));
+      stack_offset += kDoubleSize;
+    }
+  }
+  addiu(sp, sp, stack_offset);
+}
+
+
+void MacroAssembler::MultiPopReversedFPU(RegList regs) {
+  CpuFeatures::Scope scope(FPU);
+  int16_t stack_offset = 0;
+
+  for (int16_t i = kNumRegisters; i > 0; i--) {
+    if ((regs & (1 << i)) != 0) {
+      ldc1(FPURegister::from_code(i), MemOperand(sp, stack_offset));
+      stack_offset += kDoubleSize;
+    }
+  }
+  addiu(sp, sp, stack_offset);
 }
 
 
@@ -2753,6 +2815,46 @@
 }
 
 
+void MacroAssembler::AllocateTwoByteSlicedString(Register result,
+                                                 Register length,
+                                                 Register scratch1,
+                                                 Register scratch2,
+                                                 Label* gc_required) {
+  AllocateInNewSpace(SlicedString::kSize,
+                     result,
+                     scratch1,
+                     scratch2,
+                     gc_required,
+                     TAG_OBJECT);
+
+  InitializeNewString(result,
+                      length,
+                      Heap::kSlicedStringMapRootIndex,
+                      scratch1,
+                      scratch2);
+}
+
+
+void MacroAssembler::AllocateAsciiSlicedString(Register result,
+                                               Register length,
+                                               Register scratch1,
+                                               Register scratch2,
+                                               Label* gc_required) {
+  AllocateInNewSpace(SlicedString::kSize,
+                     result,
+                     scratch1,
+                     scratch2,
+                     gc_required,
+                     TAG_OBJECT);
+
+  InitializeNewString(result,
+                      length,
+                      Heap::kSlicedAsciiStringMapRootIndex,
+                      scratch1,
+                      scratch2);
+}
+
+
 // Allocates a heap number or jumps to the label if the young space is full and
 // a scavenge is needed.
 void MacroAssembler::AllocateHeapNumber(Register result,
@@ -4151,11 +4253,9 @@
   // mips, even though those argument slots are not normally used.
   // Remaining arguments are pushed on the stack, above (higher address than)
   // the argument slots.
-  ASSERT(StandardFrameConstants::kCArgsSlotsSize % kPointerSize == 0);
   int stack_passed_arguments = ((num_arguments <= kRegisterPassedArguments) ?
                                  0 : num_arguments - kRegisterPassedArguments) +
-                               (StandardFrameConstants::kCArgsSlotsSize /
-                               kPointerSize);
+                                kCArgSlotCount;
   if (frame_alignment > kPointerSize) {
     // Make stack end at alignment and make room for num_arguments - 4 words
     // and the original value of sp.
@@ -4227,11 +4327,9 @@
 
   Call(function);
 
-  ASSERT(StandardFrameConstants::kCArgsSlotsSize % kPointerSize == 0);
   int stack_passed_arguments = ((num_arguments <= kRegisterPassedArguments) ?
                                 0 : num_arguments - kRegisterPassedArguments) +
-                               (StandardFrameConstants::kCArgsSlotsSize /
-                               kPointerSize);
+                               kCArgSlotCount;
 
   if (OS::ActivationFrameAlignment() > kPointerSize) {
     lw(sp, MemOperand(sp, stack_passed_arguments * kPointerSize));
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index 0fcf6f1..5dd012e 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -362,6 +362,16 @@
                                Register scratch1,
                                Register scratch2,
                                Label* gc_required);
+  void AllocateTwoByteSlicedString(Register result,
+                                   Register length,
+                                   Register scratch1,
+                                   Register scratch2,
+                                   Label* gc_required);
+  void AllocateAsciiSlicedString(Register result,
+                                 Register length,
+                                 Register scratch1,
+                                 Register scratch2,
+                                 Label* gc_required);
 
   // Allocates a heap number or jumps to the gc_required label if the young
   // space is full and a scavenge is needed. All registers are clobbered also
@@ -442,6 +452,9 @@
   void MultiPush(RegList regs);
   void MultiPushReversed(RegList regs);
 
+  void MultiPushFPU(RegList regs);
+  void MultiPushReversedFPU(RegList regs);
+
   // Lower case push() for compatibility with arch-independent code.
   void push(Register src) {
     Addu(sp, sp, Operand(-kPointerSize));
@@ -487,6 +500,9 @@
   void MultiPop(RegList regs);
   void MultiPopReversed(RegList regs);
 
+  void MultiPopFPU(RegList regs);
+  void MultiPopReversedFPU(RegList regs);
+
   // Lower case pop() for compatibility with arch-independent code.
   void pop(Register dst) {
     lw(dst, MemOperand(sp, 0));
@@ -1197,10 +1213,9 @@
 // Generate a MemOperand for storing arguments 5..N on the stack
 // when calling CallCFunction().
 static inline MemOperand CFunctionArgumentOperand(int index) {
-  ASSERT(index > StandardFrameConstants::kCArgSlotCount);
+  ASSERT(index > kCArgSlotCount);
   // Argument 5 takes the slot just past the four Arg-slots.
-  int offset =
-      (index - 5) * kPointerSize + StandardFrameConstants::kCArgsSlotsSize;
+  int offset = (index - 5) * kPointerSize + kCArgsSlotsSize;
   return MemOperand(sp, offset);
 }
 
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index 3b38695..7628237 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -2716,7 +2716,7 @@
   // Store remaining arguments on stack, from low to high memory.
   intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack);
   for (int i = 4; i < argument_count; i++) {
-    stack_argument[i - 4 + kArgsSlotsNum] = va_arg(parameters, int32_t);
+    stack_argument[i - 4 + kCArgSlotCount] = va_arg(parameters, int32_t);
   }
   va_end(parameters);
   set_register(sp, entry_stack);
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index c17a658..d0f06e4 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -3501,7 +3501,7 @@
 
   // We are not untagging smi key and instead work with it
   // as if it was premultiplied by 2.
-  ASSERT((kSmiTag == 0) && (kSmiTagSize == 1));
+  STATIC_ASSERT((kSmiTag == 0) && (kSmiTagSize == 1));
 
   Register value = a2;
   switch (elements_kind) {
@@ -4213,7 +4213,7 @@
 
   // Load the result and make sure it's not the hole.
   __ Addu(a3, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
-  ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
+  STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
   __ sll(t0, a0, kPointerSizeLog2 - kSmiTagSize);
   __ Addu(t0, t0, a3);
   __ lw(t0, MemOperand(t0));
@@ -4344,7 +4344,7 @@
 
   __ Addu(scratch,
           elements_reg, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
-  ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
+  STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
   __ sll(scratch2, key_reg, kPointerSizeLog2 - kSmiTagSize);
   __ Addu(scratch3, scratch2, scratch);
   __ sw(value_reg, MemOperand(scratch3));
diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index 4f5fe96..a791dbb 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -29,8 +29,6 @@
 #include <bzlib.h>
 #endif
 #include <signal.h>
-#include <string>
-#include <map>
 
 #include "v8.h"
 
@@ -86,16 +84,6 @@
 };
 
 
-// We statically allocate a set of local counters to be used if we
-// don't want to store the stats in a memory-mapped file
-static CounterCollection local_counters;
-
-
-typedef std::map<std::string, int*> CounterMap;
-typedef std::map<std::string, int*>::iterator CounterMapIterator;
-static CounterMap counter_table_;
-
-
 class Compressor {
  public:
   virtual ~Compressor() {}
diff --git a/src/objects.cc b/src/objects.cc
index 0a9598c..76b57d8 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -7009,7 +7009,7 @@
           JSFunction* function =
               JSFunction::cast(LiteralArray()->get(function_id));
           unsigned height = iterator.Next();
-          PrintF(out, "{ast_id=%d, \nfunction=", ast_id);
+          PrintF(out, "{ast_id=%d, function=", ast_id);
           function->PrintName(out);
           PrintF(out, ", height=%u}", height);
           break;
diff --git a/src/parser.cc b/src/parser.cc
index 615c6ea..30d6f22 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -30,6 +30,7 @@
 #include "api.h"
 #include "ast-inl.h"
 #include "bootstrapper.h"
+#include "char-predicates-inl.h"
 #include "codegen.h"
 #include "compiler.h"
 #include "func-name-inferrer.h"
@@ -532,7 +533,7 @@
   parser->top_scope_ = scope;
   parser->lexical_scope_ = this;
   parser->with_nesting_level_ = 0;
-  isolate->set_ast_node_id(AstNode::kFunctionEntryId + 1);
+  isolate->set_ast_node_id(AstNode::kDeclarationsId + 1);
 }
 
 
@@ -647,6 +648,11 @@
     if (ok && top_scope_->is_strict_mode()) {
       CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
     }
+
+    if (ok && harmony_block_scoping_) {
+      CheckConflictingVarDeclarations(scope, &ok);
+    }
+
     if (ok) {
       result = new(zone()) FunctionLiteral(
           isolate(),
@@ -1343,14 +1349,32 @@
       // Declare the name.
       var = declaration_scope->DeclareLocal(name, mode);
     } else {
-      // The name was declared before; check for conflicting re-declarations.
-      // We have a conflict if either of the declarations is not a var. There
-      // is similar code in runtime.cc in the Declare functions.
+      // The name was declared in this scope before; check for conflicting
+      // re-declarations. We have a conflict if either of the declarations is
+      // not a var. There is similar code in runtime.cc in the Declare
+      // functions. The function CheckNonConflictingScope checks for conflicting
+      // var and let bindings from different scopes whereas this is a check for
+      // conflicting declarations within the same scope. This check also covers
+      //
+      // function () { let x; { var x; } }
+      //
+      // because the var declaration is hoisted to the function scope where 'x'
+      // is already bound.
       if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) {
         // We only have vars, consts and lets in declarations.
         ASSERT(var->mode() == Variable::VAR ||
                var->mode() == Variable::CONST ||
                var->mode() == Variable::LET);
+        if (harmony_block_scoping_) {
+          // In harmony mode we treat re-declarations as early errors. See
+          // ES5 16 for a definition of early errors.
+          SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
+          const char* elms[2] = { "Variable", *c_string };
+          Vector<const char*> args(elms, 2);
+          ReportMessage("redeclaration", args);
+          *ok = false;
+          return NULL;
+        }
         const char* type = (var->mode() == Variable::VAR) ? "var" :
                            (var->mode() == Variable::CONST) ? "const" : "let";
         Handle<String> type_string =
@@ -1379,8 +1403,10 @@
   // semantic issue as long as we keep the source order, but it may be
   // a performance issue since it may lead to repeated
   // Runtime::DeclareContextSlot() calls.
-  VariableProxy* proxy = declaration_scope->NewUnresolved(name, false);
-  declaration_scope->AddDeclaration(new(zone()) Declaration(proxy, mode, fun));
+  VariableProxy* proxy = declaration_scope->NewUnresolved(
+      name, false, scanner().location().beg_pos);
+  declaration_scope->AddDeclaration(
+      new(zone()) Declaration(proxy, mode, fun, top_scope_));
 
   // For global const variables we bind the proxy to a variable.
   if (mode == Variable::CONST && declaration_scope->is_global_scope()) {
@@ -1534,9 +1560,6 @@
   Scope* block_scope = NewScope(top_scope_,
                                 Scope::BLOCK_SCOPE,
                                 inside_with());
-  body->set_block_scope(block_scope);
-  block_scope->DeclareLocal(isolate()->factory()->block_scope_symbol(),
-                            Variable::VAR);
   if (top_scope_->is_strict_mode()) {
     block_scope->EnableStrictMode();
   }
@@ -1559,21 +1582,28 @@
     }
   }
   Expect(Token::RBRACE, CHECK_OK);
-
-  // Create exit block.
-  Block* exit = new(zone()) Block(isolate(), NULL, 1, false);
-  exit->AddStatement(new(zone()) ExitContextStatement());
-
-  // Create a try-finally statement.
-  TryFinallyStatement* try_finally =
-      new(zone()) TryFinallyStatement(body, exit);
-  try_finally->set_escaping_targets(collector.targets());
   top_scope_ = saved_scope;
 
-  // Create a result block.
-  Block* result = new(zone()) Block(isolate(), NULL, 1, false);
-  result->AddStatement(try_finally);
-  return result;
+  block_scope = block_scope->FinalizeBlockScope();
+  body->set_block_scope(block_scope);
+
+  if (block_scope != NULL) {
+    // Create exit block.
+    Block* exit = new(zone()) Block(isolate(), NULL, 1, false);
+    exit->AddStatement(new(zone()) ExitContextStatement());
+
+    // Create a try-finally statement.
+    TryFinallyStatement* try_finally =
+        new(zone()) TryFinallyStatement(body, exit);
+    try_finally->set_escaping_targets(collector.targets());
+
+    // Create a result block.
+    Block* result = new(zone()) Block(isolate(), NULL, 1, false);
+    result->AddStatement(try_finally);
+    return result;
+  } else {
+    return body;
+  }
 }
 
 
@@ -2207,7 +2237,9 @@
       if (top_scope_->is_strict_mode()) {
         catch_scope->EnableStrictMode();
       }
-      catch_variable = catch_scope->DeclareLocal(name, Variable::VAR);
+      Variable::Mode mode = harmony_block_scoping_
+          ? Variable::LET : Variable::VAR;
+      catch_variable = catch_scope->DeclareLocal(name, mode);
       catch_block = new(zone()) Block(isolate(), NULL, 2, false);
 
       Scope* saved_scope = top_scope_;
@@ -3736,7 +3768,10 @@
         reserved_loc = scanner().location();
       }
 
-      top_scope_->DeclareParameter(param_name);
+      top_scope_->DeclareParameter(param_name,
+                                   harmony_block_scoping_
+                                   ? Variable::LET
+                                   : Variable::VAR);
       num_parameters++;
       if (num_parameters > kMaxNumFunctionParameters) {
         ReportMessageAt(scanner().location(), "too_many_parameters",
@@ -3863,6 +3898,10 @@
     }
   }
 
+  if (harmony_block_scoping_) {
+    CheckConflictingVarDeclarations(scope, CHECK_OK);
+  }
+
   FunctionLiteral* function_literal =
       new(zone()) FunctionLiteral(isolate(),
                                   function_name,
@@ -4069,6 +4108,25 @@
 }
 
 
+void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
+  Declaration* decl = scope->CheckConflictingVarDeclarations();
+  if (decl != NULL) {
+    // In harmony mode we treat conflicting variable bindinds as early
+    // errors. See ES5 16 for a definition of early errors.
+    Handle<String> name = decl->proxy()->name();
+    SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
+    const char* elms[2] = { "Variable", *c_string };
+    Vector<const char*> args(elms, 2);
+    int position = decl->proxy()->position();
+    Scanner::Location location = position == RelocInfo::kNoPosition
+        ? Scanner::Location::invalid()
+        : Scanner::Location(position, position + 1);
+    ReportMessageAt(location, "redeclaration", args);
+    *ok = false;
+  }
+}
+
+
 // This function reads an identifier name and determines whether or not it
 // is 'get' or 'set'.
 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
diff --git a/src/parser.h b/src/parser.h
index 686dac8..381ff27 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -645,6 +645,17 @@
   // Strict mode octal literal validation.
   void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
 
+  // For harmony block scoping mode: Check if the scope has conflicting var/let
+  // declarations from different scopes. It covers for example
+  //
+  // function f() { { { var x; } let x; } }
+  // function g() { { var x; let x; } }
+  //
+  // The var declarations are hoisted to the function scope, but originate from
+  // a scope where the name has also been let bound or the var declaration is
+  // hoisted over such a scope.
+  void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
+
   // Parser support
   VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
                          FunctionLiteral* fun,
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 362bf47..b152dae 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -130,13 +130,7 @@
 
 
 uint64_t OS::CpuFeaturesImpliedByPlatform() {
-#if(defined(__mips_hard_float) && __mips_hard_float != 0)
-    // Here gcc is telling us that we are on an MIPS and gcc is assuming that we
-    // have FPU instructions.  If gcc can assume it then so can we.
-    return 1u << FPU;
-#else
   return 0;  // Linux runs on anything.
-#endif
 }
 
 
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index db9f892..74dfbf4 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -1195,12 +1195,9 @@
                                    int children_count,
                                    int retainers_count) {
   ASSERT(raw_entries_ == NULL);
-  raw_entries_ = NewArray<char>(
-      HeapEntry::EntriesSize(entries_count, children_count, retainers_count));
-#ifdef DEBUG
   raw_entries_size_ =
       HeapEntry::EntriesSize(entries_count, children_count, retainers_count);
-#endif
+  raw_entries_ = NewArray<char>(raw_entries_size_);
 }
 
 
@@ -2984,10 +2981,19 @@
   bool aborted_;
 };
 
+const int HeapSnapshotJSONSerializer::kMaxSerializableSnapshotRawSize =
+    256 * MB;
+
 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) {
   ASSERT(writer_ == NULL);
   writer_ = new OutputStreamWriter(stream);
 
+  HeapSnapshot* original_snapshot = NULL;
+  if (snapshot_->raw_entries_size() >= kMaxSerializableSnapshotRawSize) {
+    // The snapshot is too big. Serialize a fake snapshot.
+    original_snapshot = snapshot_;
+    snapshot_ = CreateFakeSnapshot();
+  }
   // Since nodes graph is cyclic, we need the first pass to enumerate
   // them. Strings can be serialized in one pass.
   EnumerateNodes();
@@ -2995,6 +3001,26 @@
 
   delete writer_;
   writer_ = NULL;
+
+  if (original_snapshot != NULL) {
+    delete snapshot_;
+    snapshot_ = original_snapshot;
+  }
+}
+
+
+HeapSnapshot* HeapSnapshotJSONSerializer::CreateFakeSnapshot() {
+  HeapSnapshot* result = new HeapSnapshot(snapshot_->collection(),
+                                          HeapSnapshot::kFull,
+                                          snapshot_->title(),
+                                          snapshot_->uid());
+  result->AllocateEntries(2, 1, 0);
+  HeapEntry* root = result->AddRootEntry(1);
+  HeapEntry* message = result->AddEntry(
+      HeapEntry::kString, "The snapshot is too big", 0, 4, 0, 0);
+  root->SetUnidirElementReference(0, 1, message);
+  result->SetDominatorsToSelf();
+  return result;
 }
 
 
diff --git a/src/profile-generator.h b/src/profile-generator.h
index 9ab44a1..6bada36 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -654,6 +654,7 @@
   HeapEntry* gc_roots() { return gc_roots_entry_; }
   HeapEntry* natives_root() { return natives_root_entry_; }
   List<HeapEntry*>* entries() { return &entries_; }
+  int raw_entries_size() { return raw_entries_size_; }
 
   void AllocateEntries(
       int entries_count, int children_count, int retainers_count);
@@ -689,9 +690,7 @@
   char* raw_entries_;
   List<HeapEntry*> entries_;
   bool entries_sorted_;
-#ifdef DEBUG
   int raw_entries_size_;
-#endif
 
   friend class HeapSnapshotTester;
 
@@ -1097,6 +1096,7 @@
   }
 
   void EnumerateNodes();
+  HeapSnapshot* CreateFakeSnapshot();
   int GetNodeId(HeapEntry* entry);
   int GetStringId(const char* s);
   void SerializeEdge(HeapGraphEdge* edge);
@@ -1108,6 +1108,8 @@
   void SerializeStrings();
   void SortHashMap(HashMap* map, List<HashMap::Entry*>* sorted_entries);
 
+  static const int kMaxSerializableSnapshotRawSize;
+
   HeapSnapshot* snapshot_;
   HashMap nodes_;
   HashMap strings_;
diff --git a/src/regexp.js b/src/regexp.js
index a7f42d5..38d4496 100644
--- a/src/regexp.js
+++ b/src/regexp.js
@@ -405,7 +405,8 @@
 
 // -------------------------------------------------------------------
 
-function SetupRegExp() {
+function SetUpRegExp() {
+  %CheckIsBootstrapping();
   %FunctionSetInstanceClassName($RegExp, 'RegExp');
   %FunctionSetPrototype($RegExp, new $Object());
   %SetProperty($RegExp.prototype, 'constructor', $RegExp, DONT_ENUM);
@@ -484,5 +485,4 @@
   }
 }
 
-
-SetupRegExp();
+SetUpRegExp();
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 917f6d0..26d8846 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -115,10 +115,8 @@
   }
 
   SharedFunctionInfo* shared = function->shared();
-  // If the code is not optimizable or references context slots, don't try OSR.
-  if (!shared->code()->optimizable() || !shared->allows_lazy_compilation()) {
-    return;
-  }
+  // If the code is not optimizable, don't try OSR.
+  if (!shared->code()->optimizable()) return;
 
   // We are not prepared to do OSR for a function that already has an
   // allocated arguments object.  The optimized code would bypass it for
diff --git a/src/runtime.cc b/src/runtime.cc
index 9d3bb1d..e894bf2 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -32,6 +32,7 @@
 #include "accessors.h"
 #include "api.h"
 #include "arguments.h"
+#include "bootstrapper.h"
 #include "codegen.h"
 #include "compilation-cache.h"
 #include "compiler.h"
@@ -1149,22 +1150,14 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
-  ASSERT(args.length() == 4);
+  ASSERT(args.length() == 3);
   HandleScope scope(isolate);
   Handle<GlobalObject> global = Handle<GlobalObject>(
       isolate->context()->global());
 
   Handle<Context> context = args.at<Context>(0);
   CONVERT_ARG_CHECKED(FixedArray, pairs, 1);
-  bool is_eval = args.smi_at(2) == 1;
-  StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
-  ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
-
-  // Compute the property attributes. According to ECMA-262, section
-  // 13, page 71, the property must be read-only and
-  // non-deletable. However, neither SpiderMonkey nor KJS creates the
-  // property as read-only, so we don't either.
-  PropertyAttributes base = is_eval ? NONE : DONT_DELETE;
+  CONVERT_SMI_ARG_CHECKED(flags, 2);
 
   // Traverse the name/value pairs and set the properties.
   int length = pairs->length();
@@ -1177,7 +1170,7 @@
     // assign to it when evaluating the assignment for "const x =
     // <expr>" the initial value is the hole.
     bool is_const_property = value->IsTheHole();
-
+    bool is_function_declaration = false;
     if (value->IsUndefined() || is_const_property) {
       // Lookup the property in the global object, and don't set the
       // value of the variable if the property is already there.
@@ -1226,6 +1219,7 @@
         }
       }
     } else {
+      is_function_declaration = true;
       // Copy the function and update its context. Use it as value.
       Handle<SharedFunctionInfo> shared =
           Handle<SharedFunctionInfo>::cast(value);
@@ -1239,10 +1233,6 @@
     LookupResult lookup;
     global->LocalLookup(*name, &lookup);
 
-    PropertyAttributes attributes = is_const_property
-        ? static_cast<PropertyAttributes>(base | READ_ONLY)
-        : base;
-
     // There's a local property that we need to overwrite because
     // we're either declaring a function or there's an interceptor
     // that claims the property is absent.
@@ -1257,6 +1247,19 @@
       return ThrowRedeclarationError(isolate, type, name);
     }
 
+    // Compute the property attributes. According to ECMA-262, section
+    // 13, page 71, the property must be read-only and
+    // non-deletable. However, neither SpiderMonkey nor KJS creates the
+    // property as read-only, so we don't either.
+    int attr = NONE;
+    if ((flags & kDeclareGlobalsEvalFlag) == 0) {
+      attr |= DONT_DELETE;
+    }
+    bool is_native = (flags & kDeclareGlobalsNativeFlag) != 0;
+    if (is_const_property || (is_native && is_function_declaration)) {
+      attr |= READ_ONLY;
+    }
+
     // Safari does not allow the invocation of callback setters for
     // function declarations. To mimic this behavior, we do not allow
     // the invocation of setters for function values. This makes a
@@ -1267,20 +1270,24 @@
     if (value->IsJSFunction()) {
       // Do not change DONT_DELETE to false from true.
       if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) {
-        attributes = static_cast<PropertyAttributes>(
-            attributes | (lookup.GetAttributes() & DONT_DELETE));
+        attr |= lookup.GetAttributes() & DONT_DELETE;
       }
+      PropertyAttributes attributes = static_cast<PropertyAttributes>(attr);
+
       RETURN_IF_EMPTY_HANDLE(isolate,
                              SetLocalPropertyIgnoreAttributes(global,
                                                               name,
                                                               value,
                                                               attributes));
     } else {
+      StrictModeFlag strict_mode =
+          ((flags & kDeclareGlobalsStrictModeFlag) != 0) ? kStrictMode
+                                                         : kNonStrictMode;
       RETURN_IF_EMPTY_HANDLE(isolate,
                              SetProperty(global,
                                          name,
                                          value,
-                                         attributes,
+                                         static_cast<PropertyAttributes>(attr),
                                          strict_mode));
     }
   }
@@ -2147,6 +2154,7 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
+  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
   HandleScope scope(isolate);
   ASSERT(args.length() == 2);
 
@@ -8250,6 +8258,12 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
+  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionDelegate) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
diff --git a/src/runtime.h b/src/runtime.h
index 91a19df..ddd5295 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -79,6 +79,7 @@
   F(PreventExtensions, 1, 1)\
   \
   /* Utilities */ \
+  F(CheckIsBootstrapping, 0, 1) \
   F(GetFunctionDelegate, 1, 1) \
   F(GetConstructorDelegate, 1, 1) \
   F(NewArgumentsFast, 3, 1) \
@@ -317,7 +318,7 @@
   F(StoreContextSlot, 4, 1) \
   \
   /* Declarations and initialization */ \
-  F(DeclareGlobals, 4, 1) \
+  F(DeclareGlobals, 3, 1) \
   F(DeclareContextSlot, 4, 1) \
   F(InitializeVarGlobal, -1 /* 2 or 3 */, 1) \
   F(InitializeConstGlobal, 2, 1) \
@@ -663,6 +664,16 @@
   static void PerformGC(Object* result);
 };
 
+
+//---------------------------------------------------------------------------
+// Constants used by interface to runtime functions.
+
+enum kDeclareGlobalsFlags {
+  kDeclareGlobalsEvalFlag = 1 << 0,
+  kDeclareGlobalsStrictModeFlag = 1 << 1,
+  kDeclareGlobalsNativeFlag = 1 << 2
+};
+
 } }  // namespace v8::internal
 
 #endif  // V8_RUNTIME_H_
diff --git a/src/runtime.js b/src/runtime.js
index 4b600df..61deb9b 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -48,6 +48,7 @@
 const $Function = global.Function;
 const $Boolean = global.Boolean;
 const $NaN = 0/0;
+const builtins = this;
 
 // ECMA-262 Section 11.9.3.
 function EQUALS(y) {
diff --git a/src/scanner.h b/src/scanner.h
index e66dd60..6422ee8 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -28,8 +28,6 @@
 #ifndef V8_SCANNER_H_
 #define V8_SCANNER_H_
 
-#include "token.h"
-#include "char-predicates-inl.h"
 #include "scanner-base.h"
 
 namespace v8 {
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index 0eacc83..6d1ffb9 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -131,18 +131,18 @@
   // For now, this must happen at the very end because of the
   // ordering of the scope info slots and the respective slot indices.
   if (scope->is_function_scope()) {
-    Variable* var = scope->function();
-    if (var != NULL &&
-        var->is_used() &&
-        var->AsSlot()->type() == Slot::CONTEXT) {
-      function_name_ = var->name();
+    VariableProxy* proxy = scope->function();
+    if (proxy != NULL &&
+        proxy->var()->is_used() &&
+        proxy->var()->IsContextSlot()) {
+      function_name_ = proxy->name();
       // Note that we must not find the function name in the context slot
       // list - instead it must be handled separately in the
       // Contexts::Lookup() function. Thus record an empty symbol here so we
       // get the correct number of context slots.
-      ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
+      ASSERT(proxy->var()->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
              context_slots_.length());
-      ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
+      ASSERT(proxy->var()->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
              context_modes_.length());
       context_slots_.Add(FACTORY->empty_symbol());
       context_modes_.Add(Variable::INTERNAL);
diff --git a/src/scopes.cc b/src/scopes.cc
index ddde48a..15634d0 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -331,6 +331,35 @@
 }
 
 
+Scope* Scope::FinalizeBlockScope() {
+  ASSERT(is_block_scope());
+  ASSERT(temps_.is_empty());
+  ASSERT(params_.is_empty());
+
+  if (num_var_or_const() > 0) return this;
+
+  // Remove this scope from outer scope.
+  for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) {
+    if (outer_scope_->inner_scopes_[i] == this) {
+      outer_scope_->inner_scopes_.Remove(i);
+      break;
+    }
+  }
+
+  // Reparent inner scopes.
+  for (int i = 0; i < inner_scopes_.length(); i++) {
+    outer_scope()->AddInnerScope(inner_scopes_[i]);
+  }
+
+  // Move unresolved variables
+  for (int i = 0; i < unresolved_.length(); i++) {
+    outer_scope()->unresolved_.Add(unresolved_[i]);
+  }
+
+  return NULL;
+}
+
+
 Variable* Scope::LocalLookup(Handle<String> name) {
   Variable* result = variables_.Lookup(name);
   if (result != NULL || scope_info_.is_null()) {
@@ -378,16 +407,18 @@
 
 Variable* Scope::DeclareFunctionVar(Handle<String> name) {
   ASSERT(is_function_scope() && function_ == NULL);
-  function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL);
-  return function_;
+  Variable* function_var =
+      new Variable(this, name, Variable::CONST, true, Variable::NORMAL);
+  function_ = new(isolate_->zone()) VariableProxy(isolate_, function_var);
+  return function_->var();
 }
 
 
-void Scope::DeclareParameter(Handle<String> name) {
+void Scope::DeclareParameter(Handle<String> name, Variable::Mode mode) {
   ASSERT(!already_resolved());
   ASSERT(is_function_scope());
   Variable* var =
-      variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL);
+      variables_.Declare(this, name, mode, true, Variable::NORMAL);
   params_.Add(var);
 }
 
@@ -467,6 +498,28 @@
 }
 
 
+Declaration* Scope::CheckConflictingVarDeclarations() {
+  int length = decls_.length();
+  for (int i = 0; i < length; i++) {
+    Declaration* decl = decls_[i];
+    if (decl->mode() != Variable::VAR) continue;
+    Handle<String> name = decl->proxy()->name();
+    bool cond = true;
+    for (Scope* scope = decl->scope(); cond ; scope = scope->outer_scope_) {
+      // There is a conflict if there exists a non-VAR binding.
+      Variable* other_var = scope->variables_.Lookup(name);
+      if (other_var != NULL && other_var->mode() != Variable::VAR) {
+        return decl;
+      }
+
+      // Include declaration scope in the iteration but stop after.
+      if (!scope->is_block_scope() && !scope->is_catch_scope()) cond = false;
+    }
+  }
+  return NULL;
+}
+
+
 template<class Allocator>
 void Scope::CollectUsedVariables(List<Variable*, Allocator>* locals) {
   // Collect variables in this scope.
@@ -693,7 +746,7 @@
   PrettyPrinter printer;
   Indent(n1, "// function var\n");
   if (function_ != NULL) {
-    PrintVar(&printer, n1, function_);
+    PrintVar(&printer, n1, function_->var());
   }
 
   Indent(n1, "// temporary vars\n");
@@ -774,7 +827,7 @@
     // the name of named function literal is kept in an intermediate scope
     // in between this scope and the next outer scope.)
     if (function_ != NULL && function_->name().is_identical_to(name)) {
-      var = function_;
+      var = function_->var();
 
     } else if (outer_scope_ != NULL) {
       var = outer_scope_->LookupRecursive(
@@ -1092,7 +1145,7 @@
   // because of the current ScopeInfo implementation (see
   // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
   if (function_ != NULL) {
-    AllocateNonParameterLocal(function_);
+    AllocateNonParameterLocal(function_->var());
   }
 }
 
diff --git a/src/scopes.h b/src/scopes.h
index c2c4179..d18c6bc 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -112,6 +112,11 @@
 
   void Initialize(bool inside_with);
 
+  // Checks if the block scope is redundant, i.e. it does not contain any
+  // block scoped declarations. In that case it is removed from the scope
+  // tree and its children are reparented.
+  Scope* FinalizeBlockScope();
+
   // ---------------------------------------------------------------------------
   // Declarations
 
@@ -130,7 +135,7 @@
   // Declare a parameter in this scope.  When there are duplicated
   // parameters the rightmost one 'wins'.  However, the implementation
   // expects all parameters to be declared and from left to right.
-  void DeclareParameter(Handle<String> name);
+  void DeclareParameter(Handle<String> name, Variable::Mode mode);
 
   // Declare a local variable in this scope. If the variable has been
   // declared before, the previously declared variable is returned.
@@ -182,6 +187,10 @@
   // Check if the scope has (at least) one illegal redeclaration.
   bool HasIllegalRedeclaration() const { return illegal_redecl_ != NULL; }
 
+  // For harmony block scoping mode: Check if the scope has conflicting var
+  // declarations, i.e. a var declaration that has been hoisted from a nested
+  // scope over a let binding of the same name.
+  Declaration* CheckConflictingVarDeclarations();
 
   // ---------------------------------------------------------------------------
   // Scope-specific info.
@@ -235,7 +244,7 @@
   // The variable holding the function literal for named function
   // literals, or NULL.
   // Only valid for function scopes.
-  Variable* function() const {
+  VariableProxy* function() const {
     ASSERT(is_function_scope());
     return function_;
   }
@@ -354,7 +363,7 @@
   // Convenience variable.
   Variable* receiver_;
   // Function variable, if any; function scopes only.
-  Variable* function_;
+  VariableProxy* function_;
   // Convenience variable; function scopes only.
   Variable* arguments_;
 
diff --git a/src/string.js b/src/string.js
index a70eead..6f68ce0 100644
--- a/src/string.js
+++ b/src/string.js
@@ -911,50 +911,47 @@
   this.special_string = str;
 }
 
-ReplaceResultBuilder.prototype.__proto__ = null;
-
-
-ReplaceResultBuilder.prototype.add = function(str) {
-  str = TO_STRING_INLINE(str);
-  if (str.length > 0) this.elements.push(str);
-}
-
-
-ReplaceResultBuilder.prototype.addSpecialSlice = function(start, end) {
-  var len = end - start;
-  if (start < 0 || len <= 0) return;
-  if (start < 0x80000 && len < 0x800) {
-    this.elements.push((start << 11) | len);
-  } else {
-    // 0 < len <= String::kMaxLength and Smi::kMaxValue >= String::kMaxLength,
-    // so -len is a smi.
+SetUpLockedPrototype(ReplaceResultBuilder,
+  $Array("elements", "special_string"), $Array(
+  "add", function(str) {
+    str = TO_STRING_INLINE(str);
+    if (str.length > 0) this.elements.push(str);
+  },
+  "addSpecialSlice", function(start, end) {
+    var len = end - start;
+    if (start < 0 || len <= 0) return;
+    if (start < 0x80000 && len < 0x800) {
+      this.elements.push((start << 11) | len);
+    } else {
+      // 0 < len <= String::kMaxLength and Smi::kMaxValue >= String::kMaxLength,
+      // so -len is a smi.
+      var elements = this.elements;
+      elements.push(-len);
+      elements.push(start);
+    }
+  },
+  "generate", function() {
     var elements = this.elements;
-    elements.push(-len);
-    elements.push(start);
+    return %StringBuilderConcat(elements, elements.length, this.special_string);
   }
-}
-
-
-ReplaceResultBuilder.prototype.generate = function() {
-  var elements = this.elements;
-  return %StringBuilderConcat(elements, elements.length, this.special_string);
-}
+));
 
 
 // -------------------------------------------------------------------
 
-function SetupString() {
-  // Setup the constructor property on the String prototype object.
+function SetUpString() {
+  %CheckIsBootstrapping();
+  // Set up the constructor property on the String prototype object.
   %SetProperty($String.prototype, "constructor", $String, DONT_ENUM);
 
 
-  // Setup the non-enumerable functions on the String object.
+  // Set up the non-enumerable functions on the String object.
   InstallFunctions($String, DONT_ENUM, $Array(
     "fromCharCode", StringFromCharCode
   ));
 
 
-  // Setup the non-enumerable functions on the String prototype object.
+  // Set up the non-enumerable functions on the String prototype object.
   InstallFunctionsOnHiddenPrototype($String.prototype, DONT_ENUM, $Array(
     "valueOf", StringValueOf,
     "toString", StringToString,
@@ -994,5 +991,4 @@
   ));
 }
 
-
-SetupString();
+SetUpString();
diff --git a/src/uri.js b/src/uri.js
index 72ca6f1..c910d75 100644
--- a/src/uri.js
+++ b/src/uri.js
@@ -392,8 +392,9 @@
 
 // -------------------------------------------------------------------
 
-function SetupURI() {
-  // Setup non-enumerable URI functions on the global object and set
+function SetUpUri() {
+  %CheckIsBootstrapping();
+  // Set up non-enumerable URI functions on the global object and set
   // their names.
   InstallFunctions(global, DONT_ENUM, $Array(
     "escape", URIEscape,
@@ -405,4 +406,4 @@
   ));
 }
 
-SetupURI();
+SetUpUri();
diff --git a/src/v8natives.js b/src/v8natives.js
index 035fd2e..03d1585 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -55,6 +55,15 @@
     var f = functions[i + 1];
     %FunctionSetName(f, key);
     %FunctionRemovePrototype(f);
+    // We match firefox on this, but not Safari (which does not have the
+    // property at all).
+    %IgnoreAttributesAndSetProperty(f, "caller",
+                                    null,
+                                    DONT_ENUM | DONT_DELETE);
+    %IgnoreAttributesAndSetProperty(f, "arguments",
+                                    null,
+                                    DONT_ENUM | DONT_DELETE);
+
     %SetProperty(object, key, f, attributes);
     %SetNativeFlag(f);
   }
@@ -66,12 +75,48 @@
 // functions on String.prototype etc. and then restore the old function
 // with delete.  See http://code.google.com/p/chromium/issues/detail?id=1717
 function InstallFunctionsOnHiddenPrototype(object, attributes, functions) {
+  %CheckIsBootstrapping();
   var hidden_prototype = new $Object();
   %SetHiddenPrototype(object, hidden_prototype);
   InstallFunctions(hidden_prototype, attributes, functions);
 }
 
 
+// Prevents changes to the prototype of a built-infunction.
+// The "prototype" property of the function object is made non-configurable,
+// and the prototype object is made non-extensible. The latter prevents
+// changing the __proto__ property.
+function SetUpLockedPrototype(constructor, fields, methods) {
+  %CheckIsBootstrapping();
+  var prototype = constructor.prototype;
+  // Install functions first, because this function is used to initialize
+  // PropertyDescriptor itself.
+  var property_count = (methods.length >> 1) + (fields ? fields.length : 0);
+  if (property_count >= 4) {
+    %OptimizeObjectForAddingMultipleProperties(prototype, property_count);
+  }
+  if (fields) {
+    for (var i = 0; i < fields.length; i++) {
+      %SetProperty(prototype, fields[i], void 0, DONT_ENUM | DONT_DELETE);
+    }
+  }
+  for (var i = 0; i < methods.length; i += 2) {
+    var key = methods[i];
+    var f = methods[i + 1];
+    %SetProperty(prototype, key, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
+    %SetNativeFlag(f);
+  }
+  prototype.__proto__ = null;
+  %PreventExtensions(prototype);
+  %ToFastProperties(prototype);
+
+  var desc = GetOwnProperty(constructor, "prototype");
+  desc.setWritable(false);
+  desc.setConfigurable(false);
+  DefineOwnProperty(constructor, "prototype", desc, false);
+}
+
+
 // ----------------------------------------------------------------------------
 
 
@@ -106,13 +151,16 @@
       // Truncate number.
       return string | 0;
     }
+    string = TO_STRING_INLINE(string);
     radix = radix | 0;
   } else {
+    // The spec says ToString should be evaluated before ToInt32.
+    string = TO_STRING_INLINE(string);
     radix = TO_INT32(radix);
     if (!(radix == 0 || (2 <= radix && radix <= 36)))
       return $NaN;
   }
-  string = TO_STRING_INLINE(string);
+
   if (%_HasCachedArrayIndex(string) &&
       (radix == 0 || radix == 10)) {
     return %_GetCachedArrayIndex(string);
@@ -159,8 +207,9 @@
 
 // ----------------------------------------------------------------------------
 
-
-function SetupGlobal() {
+// Set up global object.
+function SetUpGlobal() {
+  %CheckIsBootstrapping();
   // ECMA 262 - 15.1.1.1.
   %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE);
 
@@ -170,7 +219,7 @@
   // ECMA-262 - 15.1.1.3.
   %SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
 
-  // Setup non-enumerable function on the global object.
+  // Set up non-enumerable function on the global object.
   InstallFunctions(global, DONT_ENUM, $Array(
     "isNaN", GlobalIsNaN,
     "isFinite", GlobalIsFinite,
@@ -180,8 +229,7 @@
   ));
 }
 
-SetupGlobal();
-
+SetUpGlobal();
 
 // ----------------------------------------------------------------------------
 // Boolean (first part of definition)
@@ -478,106 +526,83 @@
   this.hasSetter_ = false;
 }
 
-PropertyDescriptor.prototype.__proto__ = null;
-
-PropertyDescriptor.prototype.toString = function() {
-  return "[object PropertyDescriptor]";
-};
-
-PropertyDescriptor.prototype.setValue = function(value) {
-  this.value_ = value;
-  this.hasValue_ = true;
-}
-
-
-PropertyDescriptor.prototype.getValue = function() {
-  return this.value_;
-}
-
-
-PropertyDescriptor.prototype.hasValue = function() {
-  return this.hasValue_;
-}
-
-
-PropertyDescriptor.prototype.setEnumerable = function(enumerable) {
-  this.enumerable_ = enumerable;
-  this.hasEnumerable_ = true;
-}
-
-
-PropertyDescriptor.prototype.isEnumerable = function () {
-  return this.enumerable_;
-}
-
-
-PropertyDescriptor.prototype.hasEnumerable = function() {
-  return this.hasEnumerable_;
-}
-
-
-PropertyDescriptor.prototype.setWritable = function(writable) {
-  this.writable_ = writable;
-  this.hasWritable_ = true;
-}
-
-
-PropertyDescriptor.prototype.isWritable = function() {
-  return this.writable_;
-}
-
-
-PropertyDescriptor.prototype.hasWritable = function() {
-  return this.hasWritable_;
-}
-
-
-PropertyDescriptor.prototype.setConfigurable = function(configurable) {
-  this.configurable_ = configurable;
-  this.hasConfigurable_ = true;
-}
-
-
-PropertyDescriptor.prototype.hasConfigurable = function() {
-  return this.hasConfigurable_;
-}
-
-
-PropertyDescriptor.prototype.isConfigurable = function() {
-  return this.configurable_;
-}
-
-
-PropertyDescriptor.prototype.setGet = function(get) {
-  this.get_ = get;
-  this.hasGetter_ = true;
-}
-
-
-PropertyDescriptor.prototype.getGet = function() {
-  return this.get_;
-}
-
-
-PropertyDescriptor.prototype.hasGetter = function() {
-  return this.hasGetter_;
-}
-
-
-PropertyDescriptor.prototype.setSet = function(set) {
-  this.set_ = set;
-  this.hasSetter_ = true;
-}
-
-
-PropertyDescriptor.prototype.getSet = function() {
-  return this.set_;
-}
-
-
-PropertyDescriptor.prototype.hasSetter = function() {
-  return this.hasSetter_;
-}
+SetUpLockedPrototype(PropertyDescriptor, $Array(
+    "value_",
+    "hasValue_",
+    "writable_",
+    "hasWritable_",
+    "enumerable_",
+    "hasEnumerable_",
+    "configurable_",
+    "hasConfigurable_",
+    "get_",
+    "hasGetter_",
+    "set_",
+    "hasSetter_"
+  ), $Array(
+    "toString", function() {
+      return "[object PropertyDescriptor]";
+    },
+    "setValue", function(value) {
+      this.value_ = value;
+      this.hasValue_ = true;
+    },
+    "getValue", function() {
+      return this.value_;
+    },
+    "hasValue", function() {
+      return this.hasValue_;
+    },
+    "setEnumerable", function(enumerable) {
+      this.enumerable_ = enumerable;
+        this.hasEnumerable_ = true;
+    },
+    "isEnumerable", function () {
+      return this.enumerable_;
+    },
+    "hasEnumerable", function() {
+      return this.hasEnumerable_;
+    },
+    "setWritable", function(writable) {
+      this.writable_ = writable;
+      this.hasWritable_ = true;
+    },
+    "isWritable", function() {
+      return this.writable_;
+    },
+    "hasWritable", function() {
+      return this.hasWritable_;
+    },
+    "setConfigurable", function(configurable) {
+      this.configurable_ = configurable;
+      this.hasConfigurable_ = true;
+    },
+    "hasConfigurable", function() {
+      return this.hasConfigurable_;
+    },
+    "isConfigurable", function() {
+      return this.configurable_;
+    },
+    "setGet", function(get) {
+      this.get_ = get;
+        this.hasGetter_ = true;
+    },
+    "getGet", function() {
+      return this.get_;
+    },
+    "hasGetter", function() {
+      return this.hasGetter_;
+    },
+    "setSet", function(set) {
+      this.set_ = set;
+      this.hasSetter_ = true;
+    },
+    "getSet", function() {
+      return this.set_;
+    },
+    "hasSetter", function() {
+      return this.hasSetter_;
+  }));
 
 
 // Converts an array returned from Runtime_GetOwnProperty to an actual
@@ -1165,10 +1190,11 @@
 %SetExpectedNumberOfProperties($Object, 4);
 
 // ----------------------------------------------------------------------------
+// Object
 
-
-function SetupObject() {
-  // Setup non-enumerable functions on the Object.prototype object.
+function SetUpObject() {
+  %CheckIsBootstrapping();
+  // Set Up non-enumerable functions on the Object.prototype object.
   InstallFunctions($Object.prototype, DONT_ENUM, $Array(
     "toString", ObjectToString,
     "toLocaleString", ObjectToLocaleString,
@@ -1198,8 +1224,7 @@
   ));
 }
 
-SetupObject();
-
+SetUpObject();
 
 // ----------------------------------------------------------------------------
 // Boolean
@@ -1230,14 +1255,16 @@
 // ----------------------------------------------------------------------------
 
 
-function SetupBoolean() {
+function SetUpBoolean () {
+  %CheckIsBootstrapping();
   InstallFunctions($Boolean.prototype, DONT_ENUM, $Array(
     "toString", BooleanToString,
     "valueOf", BooleanValueOf
   ));
 }
 
-SetupBoolean();
+SetUpBoolean();
+
 
 // ----------------------------------------------------------------------------
 // Number
@@ -1351,9 +1378,10 @@
 
 // ----------------------------------------------------------------------------
 
-function SetupNumber() {
+function SetUpNumber() {
+  %CheckIsBootstrapping();
   %OptimizeObjectForAddingMultipleProperties($Number.prototype, 8);
-  // Setup the constructor property on the Number prototype object.
+  // Set up the constructor property on the Number prototype object.
   %SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
 
   %OptimizeObjectForAddingMultipleProperties($Number, 5);
@@ -1382,7 +1410,7 @@
                DONT_ENUM | DONT_DELETE | READ_ONLY);
   %ToFastProperties($Number);
 
-  // Setup non-enumerable functions on the Number prototype object.
+  // Set up non-enumerable functions on the Number prototype object.
   InstallFunctions($Number.prototype, DONT_ENUM, $Array(
     "toString", NumberToString,
     "toLocaleString", NumberToLocaleString,
@@ -1393,7 +1421,7 @@
   ));
 }
 
-SetupNumber();
+SetUpNumber();
 
 
 // ----------------------------------------------------------------------------
@@ -1522,11 +1550,12 @@
 
 // ----------------------------------------------------------------------------
 
-function SetupFunction() {
+function SetUpFunction() {
+  %CheckIsBootstrapping();
   InstallFunctions($Function.prototype, DONT_ENUM, $Array(
     "bind", FunctionBind,
     "toString", FunctionToString
   ));
 }
 
-SetupFunction();
+SetUpFunction();
diff --git a/src/version.cc b/src/version.cc
index a3f306b..a004ecc 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -33,8 +33,8 @@
 // NOTE these macros are used by the SCons build script so their names
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
-#define MINOR_VERSION     5
-#define BUILD_NUMBER      10
+#define MINOR_VERSION     6
+#define BUILD_NUMBER      0
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/weakmap.js b/src/weakmap.js
index 3d261e5..6c15e30 100644
--- a/src/weakmap.js
+++ b/src/weakmap.js
@@ -80,7 +80,8 @@
 
 // -------------------------------------------------------------------
 
-function SetupWeakMap() {
+(function () {
+  %CheckIsBootstrapping();
   // Set up the WeakMap constructor function.
   %SetCode($WeakMap, WeakMapConstructor);
 
@@ -97,7 +98,4 @@
     "has", WeakMapHas,
     "delete", WeakMapDelete
   ));
-}
-
-
-SetupWeakMap();
+})();
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 9237a0a..2ae4d9f 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -3938,7 +3938,8 @@
 
   // Check for 1-byte or 2-byte string.
   __ bind(&flat_string);
-  STATIC_ASSERT(kAsciiStringTag != 0);
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
   __ testb(result_, Immediate(kStringEncodingMask));
   __ j(not_zero, &ascii_string);
 
@@ -4195,8 +4196,9 @@
   Label non_ascii, allocated, ascii_data;
   __ movl(rcx, r8);
   __ and_(rcx, r9);
-  STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
-  __ testl(rcx, Immediate(kAsciiStringTag));
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
+  __ testl(rcx, Immediate(kStringEncodingMask));
   __ j(zero, &non_ascii);
   __ bind(&ascii_data);
   // Allocate an acsii cons string.
@@ -4225,7 +4227,7 @@
   __ cmpb(r8, Immediate(kAsciiStringTag | kAsciiDataHintTag));
   __ j(equal, &ascii_data);
   // Allocate a two byte cons string.
-  __ AllocateConsString(rcx, rdi, no_reg, &string_add_runtime);
+  __ AllocateTwoByteConsString(rcx, rdi, no_reg, &string_add_runtime);
   __ jmp(&allocated);
 
   // Handle creating a flat result. First check that both strings are not
@@ -4254,10 +4256,11 @@
   // r8: instance type of first string
   // r9: instance type of second string
   Label non_ascii_string_add_flat_result;
-  STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
-  __ testl(r8, Immediate(kAsciiStringTag));
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
+  __ testl(r8, Immediate(kStringEncodingMask));
   __ j(zero, &non_ascii_string_add_flat_result);
-  __ testl(r9, Immediate(kAsciiStringTag));
+  __ testl(r9, Immediate(kStringEncodingMask));
   __ j(zero, &string_add_runtime);
 
   __ bind(&make_flat_ascii_string);
@@ -4295,7 +4298,9 @@
   // r8: instance type of first string
   // r9: instance type of first string
   __ bind(&non_ascii_string_add_flat_result);
-  __ and_(r9, Immediate(kAsciiStringTag));
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
+  __ and_(r9, Immediate(kStringEncodingMask));
   __ j(not_zero, &string_add_runtime);
   // Both strings are two byte strings. As they are short they are both
   // flat.
@@ -4639,9 +4644,6 @@
 void SubStringStub::Generate(MacroAssembler* masm) {
   Label runtime;
 
-  if (FLAG_string_slices) {
-    __ jmp(&runtime);
-  }
   // Stack frame on entry.
   //  rsp[0]: return address
   //  rsp[8]: to
@@ -4707,7 +4709,82 @@
   __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
   __ Set(rcx, 2);
 
-  __ bind(&result_longer_than_two);
+  if (FLAG_string_slices) {
+    Label copy_routine;
+    // If coming from the make_two_character_string path, the string
+    // is too short to be sliced anyways.
+    STATIC_ASSERT(2 < SlicedString::kMinLength);
+    __ jmp(&copy_routine);
+    __ bind(&result_longer_than_two);
+
+    // rax: string
+    // rbx: instance type
+    // rcx: sub string length
+    // rdx: from index (smi)
+    Label allocate_slice, sliced_string, seq_string;
+    __ cmpq(rcx, Immediate(SlicedString::kMinLength));
+    // Short slice.  Copy instead of slicing.
+    __ j(less, &copy_routine);
+    STATIC_ASSERT(kSeqStringTag == 0);
+    __ testb(rbx, Immediate(kStringRepresentationMask));
+    __ j(zero, &seq_string, Label::kNear);
+    STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
+    STATIC_ASSERT(kIsIndirectStringMask != 0);
+    __ testb(rbx, Immediate(kIsIndirectStringMask));
+    // External string.  Jump to runtime.
+    __ j(zero, &runtime);
+
+    __ testb(rbx, Immediate(kSlicedNotConsMask));
+    __ j(not_zero, &sliced_string, Label::kNear);
+    // Cons string.  Check whether it is flat, then fetch first part.
+    __ CompareRoot(FieldOperand(rax, ConsString::kSecondOffset),
+                   Heap::kEmptyStringRootIndex);
+    __ j(not_equal, &runtime);
+    __ movq(rdi, FieldOperand(rax, ConsString::kFirstOffset));
+    __ jmp(&allocate_slice, Label::kNear);
+
+    __ bind(&sliced_string);
+    // Sliced string.  Fetch parent and correct start index by offset.
+    __ addq(rdx, FieldOperand(rax, SlicedString::kOffsetOffset));
+    __ movq(rdi, FieldOperand(rax, SlicedString::kParentOffset));
+    __ jmp(&allocate_slice, Label::kNear);
+
+    __ bind(&seq_string);
+    // Sequential string.  Just move string to the right register.
+    __ movq(rdi, rax);
+
+    __ bind(&allocate_slice);
+    // edi: underlying subject string
+    // ebx: instance type of original subject string
+    // edx: offset
+    // ecx: length
+    // Allocate new sliced string.  At this point we do not reload the instance
+    // type including the string encoding because we simply rely on the info
+    // provided by the original string.  It does not matter if the original
+    // string's encoding is wrong because we always have to recheck encoding of
+    // the newly created string's parent anyways due to externalized strings.
+    Label two_byte_slice, set_slice_header;
+    STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+    STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
+    __ testb(rbx, Immediate(kStringEncodingMask));
+    __ j(zero, &two_byte_slice, Label::kNear);
+    __ AllocateAsciiSlicedString(rax, rbx, no_reg, &runtime);
+    __ jmp(&set_slice_header, Label::kNear);
+    __ bind(&two_byte_slice);
+    __ AllocateTwoByteSlicedString(rax, rbx, no_reg, &runtime);
+    __ bind(&set_slice_header);
+    __ movq(FieldOperand(rax, SlicedString::kOffsetOffset), rdx);
+    __ Integer32ToSmi(rcx, rcx);
+    __ movq(FieldOperand(rax, SlicedString::kLengthOffset), rcx);
+    __ movq(FieldOperand(rax, SlicedString::kParentOffset), rdi);
+    __ movq(FieldOperand(rax, SlicedString::kHashFieldOffset),
+           Immediate(String::kEmptyHashField));
+    __ jmp(&return_rax);
+
+    __ bind(&copy_routine);
+  } else {
+    __ bind(&result_longer_than_two);
+  }
 
   // rax: string
   // rbx: instance type
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index e77ec64..6b3f45f 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -245,6 +245,7 @@
     Comment cmnt(masm_, "[ Declarations");
     scope()->VisitIllegalRedeclaration(this);
   } else {
+    PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
     { Comment cmnt(masm_, "[ Declarations");
       // For named function expressions, declare the function name as a
       // constant.
@@ -255,7 +256,7 @@
     }
 
     { Comment cmnt(masm_, "[ Stack check");
-      PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
+      PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
       Label ok;
       __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
       __ j(above_equal, &ok, Label::kNear);
@@ -658,10 +659,11 @@
 }
 
 
-void FullCodeGenerator::EmitDeclaration(Variable* variable,
+void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
                                         Variable::Mode mode,
                                         FunctionLiteral* function) {
   Comment cmnt(masm_, "[ Declaration");
+  Variable* variable = proxy->var();
   ASSERT(variable != NULL);  // Must have been resolved.
   Slot* slot = variable->AsSlot();
   ASSERT(slot != NULL);
@@ -698,10 +700,12 @@
         int offset = Context::SlotOffset(slot->index());
         __ movq(rbx, rsi);
         __ RecordWrite(rbx, offset, result_register(), rcx);
+        PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
       } else if (mode == Variable::CONST || mode == Variable::LET) {
         __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
         __ movq(ContextOperand(rsi, slot->index()), kScratchRegister);
         // No write barrier since the hole value is in old space.
+        PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
       }
       break;
 
@@ -733,7 +737,7 @@
 
 
 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
-  EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
+  EmitDeclaration(decl->proxy(), decl->mode(), decl->fun());
 }
 
 
@@ -741,9 +745,8 @@
   // Call the runtime to declare the globals.
   __ push(rsi);  // The context is the first argument.
   __ Push(pairs);
-  __ Push(Smi::FromInt(is_eval() ? 1 : 0));
-  __ Push(Smi::FromInt(strict_mode_flag()));
-  __ CallRuntime(Runtime::kDeclareGlobals, 4);
+  __ Push(Smi::FromInt(DeclareGlobalsFlags()));
+  __ CallRuntime(Runtime::kDeclareGlobals, 3);
   // Return value is ignored.
 }
 
@@ -2069,8 +2072,13 @@
   // Push the receiver of the enclosing function and do runtime call.
   __ push(Operand(rbp, (2 + info_->scope()->num_parameters()) * kPointerSize));
 
-  // Push the strict mode flag.
-  __ Push(Smi::FromInt(strict_mode_flag()));
+  // Push the strict mode flag. In harmony mode every eval call
+  // is a strict mode eval call.
+  StrictModeFlag strict_mode = strict_mode_flag();
+  if (FLAG_harmony_block_scoping) {
+    strict_mode = kStrictMode;
+  }
+  __ Push(Smi::FromInt(strict_mode));
 
   __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
                  ? Runtime::kResolvePossiblyDirectEvalNoLookup
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index c182413..25863ed 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3251,7 +3251,8 @@
 
   // Dispatch on the encoding: ASCII or two-byte.
   Label ascii_string;
-  STATIC_ASSERT(kAsciiStringTag != 0);
+  STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
+  STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
   __ testb(result, Immediate(kStringEncodingMask));
   __ j(not_zero, &ascii_string, Label::kNear);
 
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index b51d531..2ee506d 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -3623,7 +3623,7 @@
 }
 
 
-void MacroAssembler::AllocateConsString(Register result,
+void MacroAssembler::AllocateTwoByteConsString(Register result,
                                         Register scratch1,
                                         Register scratch2,
                                         Label* gc_required) {
@@ -3659,6 +3659,42 @@
 }
 
 
+void MacroAssembler::AllocateTwoByteSlicedString(Register result,
+                                          Register scratch1,
+                                          Register scratch2,
+                                          Label* gc_required) {
+  // Allocate heap number in new space.
+  AllocateInNewSpace(SlicedString::kSize,
+                     result,
+                     scratch1,
+                     scratch2,
+                     gc_required,
+                     TAG_OBJECT);
+
+  // Set the map. The other fields are left uninitialized.
+  LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex);
+  movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
+}
+
+
+void MacroAssembler::AllocateAsciiSlicedString(Register result,
+                                               Register scratch1,
+                                               Register scratch2,
+                                               Label* gc_required) {
+  // Allocate heap number in new space.
+  AllocateInNewSpace(SlicedString::kSize,
+                     result,
+                     scratch1,
+                     scratch2,
+                     gc_required,
+                     TAG_OBJECT);
+
+  // Set the map. The other fields are left uninitialized.
+  LoadRoot(kScratchRegister, Heap::kSlicedAsciiStringMapRootIndex);
+  movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
+}
+
+
 // Copy memory, byte-by-byte, from source to destination.  Not optimized for
 // long or aligned copies.  The contents of scratch and length are destroyed.
 // Destination is incremented by length, source, length and scratch are
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 47ce01b..e7eb104 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -921,7 +921,7 @@
 
   // Allocate a raw cons string object. Only the map field of the result is
   // initialized.
-  void AllocateConsString(Register result,
+  void AllocateTwoByteConsString(Register result,
                           Register scratch1,
                           Register scratch2,
                           Label* gc_required);
@@ -930,6 +930,17 @@
                                Register scratch2,
                                Label* gc_required);
 
+  // Allocate a raw sliced string object. Only the map field of the result is
+  // initialized.
+  void AllocateTwoByteSlicedString(Register result,
+                            Register scratch1,
+                            Register scratch2,
+                            Label* gc_required);
+  void AllocateAsciiSlicedString(Register result,
+                                 Register scratch1,
+                                 Register scratch2,
+                                 Label* gc_required);
+
   // ---------------------------------------------------------------------------
   // Support functions.
 
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index c0b5316..5d0cab3 100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -35,7 +35,6 @@
       'target_name': 'cctest',
       'type': 'executable',
       'dependencies': [
-        '../../tools/gyp/v8.gyp:v8',
         'resources',
       ],
       'include_dirs': [
@@ -136,6 +135,20 @@
             'test-platform-win32.cc',
           ],
         }],
+        ['component=="shared_library"', {
+          # cctest can't be built against a shared library, so we need to
+          # depend on the underlying static target in that case.
+          'conditions': [
+            ['v8_use_snapshot=="true"', {
+              'dependencies': ['../../tools/gyp/v8.gyp:v8_snapshot'],
+            },
+            {
+              'dependencies': ['../../tools/gyp/v8.gyp:v8_nosnapshot'],
+            }],
+          ],
+        }, {
+          'dependencies': ['../../tools/gyp/v8.gyp:v8'],
+        }],
       ],
     },
     {
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 78f3756..5122da5 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -76,3 +76,7 @@
 [ $arch == mips ]
 test-deoptimization: SKIP
 test-serialize: SKIP
+
+# Tests that may time out.
+test-api/ExternalArrays: PASS || TIMEOUT
+test-api/Threading: PASS || TIMEOUT
diff --git a/test/cctest/test-assembler-mips.cc b/test/cctest/test-assembler-mips.cc
index ca11a2a..cbaa3be 100644
--- a/test/cctest/test-assembler-mips.cc
+++ b/test/cctest/test-assembler-mips.cc
@@ -1268,7 +1268,9 @@
 
   Label target;
   __ beq(v0, v1, &target);
+  __ nop();
   __ bne(v0, v1, &target);
+  __ nop();
   __ bind(&target);
   __ nop();
 }
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 9f18b60..46ac88c 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -30,14 +30,15 @@
 
 #include "v8.h"
 
-#include "string-stream.h"
-#include "cctest.h"
-#include "zone-inl.h"
-#include "parser.h"
 #include "ast.h"
+#include "char-predicates-inl.h"
+#include "cctest.h"
 #include "jsregexp.h"
+#include "parser.h"
 #include "regexp-macro-assembler.h"
 #include "regexp-macro-assembler-irregexp.h"
+#include "string-stream.h"
+#include "zone-inl.h"
 #ifdef V8_INTERPRETED_REGEXP
 #include "interpreter-irregexp.h"
 #else  // V8_INTERPRETED_REGEXP
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc
index 17020a3..55c2141 100644
--- a/test/cctest/test-strings.cc
+++ b/test/cctest/test-strings.cc
@@ -529,3 +529,32 @@
   CHECK(string->IsSlicedString());
   CHECK_EQ("bcdefghijklmnopqrstuvwxy", *(string->ToCString()));
 }
+
+
+TEST(SliceFromSlice) {
+  // This tests whether a slice that contains the entire parent string
+  // actually creates a new string (it should not).
+  FLAG_string_slices = true;
+  InitializeVM();
+  HandleScope scope;
+  v8::Local<v8::Value> result;
+  Handle<String> string;
+  const char* init = "var str = 'abcdefghijklmnopqrstuvwxyz';";
+  const char* slice = "var slice = str.slice(1,-1); slice";
+  const char* slice_from_slice = "slice.slice(1,-1);";
+
+  CompileRun(init);
+  result = CompileRun(slice);
+  CHECK(result->IsString());
+  string = v8::Utils::OpenHandle(v8::String::Cast(*result));
+  CHECK(string->IsSlicedString());
+  CHECK(SlicedString::cast(*string)->parent()->IsSeqString());
+  CHECK_EQ("bcdefghijklmnopqrstuvwxy", *(string->ToCString()));
+
+  result = CompileRun(slice_from_slice);
+  CHECK(result->IsString());
+  string = v8::Utils::OpenHandle(v8::String::Cast(*result));
+  CHECK(string->IsSlicedString());
+  CHECK(SlicedString::cast(*string)->parent()->IsSeqString());
+  CHECK_EQ("cdefghijklmnopqrstuvwx", *(string->ToCString()));
+}
diff --git a/test/es5conform/es5conform.status b/test/es5conform/es5conform.status
index 55712ba..d095a24 100644
--- a/test/es5conform/es5conform.status
+++ b/test/es5conform/es5conform.status
@@ -75,11 +75,11 @@
 # NOT IMPLEMENTED: RegExp.prototype.multiline
 chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-215: UNIMPLEMENTED
 
-# All of the tests below marked SUBSETFAIL (in 15.2.3.4) fail because 
+# All of the tests below marked SUBSETFAIL (in 15.2.3.4) fail because
 # the tests assumes that objects can not have more properties
-# than those described in the spec - but according to spec they can 
+# than those described in the spec - but according to spec they can
 # have additional properties.
-# All compareArray calls in these tests could be exchanged with a 
+# All compareArray calls in these tests could be exchanged with a
 # isSubsetOfArray call (I will upload a patch to the es5conform site).
 
 # SUBSETFAIL
diff --git a/test/mjsunit/array-constructor.js b/test/mjsunit/array-constructor.js
index 063ccde..bf5d3d6 100644
--- a/test/mjsunit/array-constructor.js
+++ b/test/mjsunit/array-constructor.js
@@ -73,7 +73,7 @@
   a = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8);
   assertArrayEquals([0, 1, 2, 3, 4, 5, 6, 7, 8], a);
   a = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
-  assertArrayEquals([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], a);  
+  assertArrayEquals([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], a);
 }
 
 
@@ -91,9 +91,9 @@
   var a = eval('[' + str + ']');
   var b = eval('new Array(' + str + ')')
   var c = eval('Array(' + str + ')')
-  assertEquals(n, a.length);  
-  assertArrayEquals(a, b);  
-  assertArrayEquals(a, c);  
+  assertEquals(n, a.length);
+  assertArrayEquals(a, b);
+  assertArrayEquals(a, c);
 }
 
 
diff --git a/test/mjsunit/array-iteration.js b/test/mjsunit/array-iteration.js
index f11b51c..0ee2e6e 100644
--- a/test/mjsunit/array-iteration.js
+++ b/test/mjsunit/array-iteration.js
@@ -134,7 +134,7 @@
   a = [0,1];
   assertFalse(a.every(function(n, index, array) { array[index] = n + 1; return n == 1;}));
   assertArrayEquals([1,1], a);
-  
+
   // Only loop through initial part of array eventhough elements are
   // added.
   a = [1,1];
@@ -156,23 +156,23 @@
 //
 (function() {
   var a = [0,1,2,3,4];
-  
+
   // Simple use.
   var result = [1,2,3,4,5];
   assertArrayEquals(result, a.map(function(n) { return n + 1; }));
   assertEquals(a, a);
-  
+
   // Use specified object as this object when calling the function.
   var o = { delta: 42 }
   result = [42,43,44,45,46];
   assertArrayEquals(result, a.map(function(n) { return this.delta + n; }, o));
-  
+
   // Modify original array.
   a = [0,1,2,3,4];
   result = [1,2,3,4,5];
   assertArrayEquals(result, a.map(function(n, index, array) { array[index] = n + 1; return n + 1;}));
   assertArrayEquals(result, a);
-  
+
   // Only loop through initial part of array eventhough elements are
   // added.
   a = [0,1,2,3,4];
@@ -197,7 +197,7 @@
   // Simple use.
   assertTrue(a.some(function(n) { return n == 3}));
   assertFalse(a.some(function(n) { return n == 5}));
-  
+
   // Use specified object as this object when calling the function.
   var o = { element: 42 };
   a = [1,42,3];
diff --git a/test/mjsunit/array-sort.js b/test/mjsunit/array-sort.js
index fd18a5b..3fa623a 100644
--- a/test/mjsunit/array-sort.js
+++ b/test/mjsunit/array-sort.js
@@ -392,7 +392,7 @@
 
 // Test that sort calls compare function with global object as receiver,
 // and with only elements of the array as arguments.
-function o(v) { 
+function o(v) {
   return {__proto__: o.prototype, val: v};
 }
 var arr = [o(1), o(2), o(4), o(8), o(16), o(32), o(64), o(128), o(256), o(-0)];
diff --git a/test/mjsunit/bugs/618.js b/test/mjsunit/bugs/618.js
index afa9929..ddc0c19 100644
--- a/test/mjsunit/bugs/618.js
+++ b/test/mjsunit/bugs/618.js
@@ -32,14 +32,14 @@
 var c1 = new C1();
 assertEquals(23, c1.x);
 assertEquals("undefined", typeof c1.y);
-  
+
 // Add setter somewhere on the prototype chain after having constructed the
 // first instance.
 C1.prototype = { set x(value) { this.y = 23; } };
 var c1 = new C1();
 assertEquals("undefined", typeof c1.x);
 assertEquals(23, c1.y);
-  
+
 // Simple class using inline constructor.
 function C2() {
   this.x = 23;
diff --git a/test/mjsunit/bugs/bug-618.js b/test/mjsunit/bugs/bug-618.js
index 8f47440..ae84326 100644
--- a/test/mjsunit/bugs/bug-618.js
+++ b/test/mjsunit/bugs/bug-618.js
@@ -33,11 +33,11 @@
   this.x = 23;
 }
 
-// If a setter is added to the prototype chain of a simple constructor setting 
-// one of the properties assigned in the constructor then this setter is 
+// If a setter is added to the prototype chain of a simple constructor setting
+// one of the properties assigned in the constructor then this setter is
 // ignored when constructing new objects from the constructor.
 
-// This only happens if the setter is added _after_ an instance has been 
+// This only happens if the setter is added _after_ an instance has been
 // created.
 
 assertEquals(23, new C().x);
diff --git a/test/mjsunit/builtins.js b/test/mjsunit/builtins.js
new file mode 100644
index 0000000..340b03d
--- /dev/null
+++ b/test/mjsunit/builtins.js
@@ -0,0 +1,83 @@
+// Copyright 2011 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.
+
+// Flags: --expose-natives-as=builtins
+
+// Checks that all function properties of the builtin object are neither
+// writable nor configurable. Also, theose functions that are actually
+// constructors (recognized by having properties on their .prototype object),
+// have only unconfigurable properties on the prototype, and the methods
+// are also non-writable.
+
+var names = Object.getOwnPropertyNames(builtins);
+
+function isFunction(obj) {
+  return typeof obj == "function";
+}
+
+function checkConstructor(func, name) {
+  // A constructor is a function with a prototype and properties on the
+  // prototype object besides "constructor";
+  if (name.charAt(0) == "$") return;
+  if (typeof func.prototype != "object") return;
+  var propNames = Object.getOwnPropertyNames(func.prototype);
+  if (propNames.length == 0 ||
+      (propNames.length == 1 && propNames[0] == "constructor")) {
+    // Not a constructor.
+    return;
+  }
+  var proto_desc = Object.getOwnPropertyDescriptor(func, "prototype");
+  assertTrue(proto_desc.hasOwnProperty("value"), name);
+  assertFalse(proto_desc.writable, name);
+  assertFalse(proto_desc.configurable, name);
+  var prototype = proto_desc.value;
+  assertEquals(null, prototype.__proto__, name);
+  assertFalse(Object.isExtensible(prototype), name);
+  for (var i = 0; i < propNames.length; i++) {
+    var propName = propNames[i];
+    if (propName == "constructor") continue;
+    var testName = name + "-" + propName;
+    var propDesc = Object.getOwnPropertyDescriptor(prototype, propName);
+    assertTrue(propDesc.hasOwnProperty("value"), testName);
+    assertFalse(propDesc.configurable, testName);
+    if (isFunction(propDesc.value)) {
+      assertFalse(propDesc.writable, testName);
+    }
+  }
+}
+
+for (var i = 0; i < names.length; i++) {
+  var name = names[i];
+  var desc = Object.getOwnPropertyDescriptor(builtins, name);
+  assertTrue(desc.hasOwnProperty("value"));
+  var value = desc.value;
+  if (isFunction(value)) {
+    assertFalse(desc.writable, name);
+    assertFalse(desc.configurable, name);
+    checkConstructor(value, name);
+  }
+}
diff --git a/test/mjsunit/compiler/global-accessors.js b/test/mjsunit/compiler/global-accessors.js
index bd031a8..337424d 100644
--- a/test/mjsunit/compiler/global-accessors.js
+++ b/test/mjsunit/compiler/global-accessors.js
@@ -26,7 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // This test tests that no bailouts are missing by not hitting asserts in debug
-// mode. 
+// mode.
 
 test_count_operation()
 test_compound_assignment()
diff --git a/test/mjsunit/const-redecl.js b/test/mjsunit/const-redecl.js
index 26d765b..9459708 100644
--- a/test/mjsunit/const-redecl.js
+++ b/test/mjsunit/const-redecl.js
@@ -55,7 +55,7 @@
 function TestGlobal(s,e) {
   // Collect the global properties before the call.
   var properties = [];
-  for (var key in this) properties.push(key); 
+  for (var key in this) properties.push(key);
   // Compute the result.
   var result;
   try {
@@ -113,7 +113,7 @@
   // Eval second definition.
   TestAll("TypeError", def0 + '; eval("' + def1 + '")');
   // Eval both definitions separately.
-  TestAll("TypeError", 'eval("' + def0 +'"); eval("' + def1 + '")');  
+  TestAll("TypeError", 'eval("' + def0 +'"); eval("' + def1 + '")');
 }
 
 
diff --git a/test/mjsunit/date-parse.js b/test/mjsunit/date-parse.js
index a1eef66..b46e39a 100644
--- a/test/mjsunit/date-parse.js
+++ b/test/mjsunit/date-parse.js
@@ -286,7 +286,7 @@
 // Negative tests.
 var testCasesNegative = [
     'May 25 2008 1:30 (PM)) UTC',  // Bad unmatched ')' after number.
-    'May 25 2008 1:30( )AM (PM)',  // 
+    'May 25 2008 1:30( )AM (PM)',  //
     'May 25 2008 AAA (GMT)'];      // Unknown word after number.
 
 testCasesNegative.forEach(function (s) {
diff --git a/test/mjsunit/debug-compile-event.js b/test/mjsunit/debug-compile-event.js
index b00a907..94dddfa 100644
--- a/test/mjsunit/debug-compile-event.js
+++ b/test/mjsunit/debug-compile-event.js
@@ -81,7 +81,7 @@
       assertTrue('context' in msg.body.script);
 
       // Check that we pick script name from //@ sourceURL, iff present
-      assertEquals(current_source.indexOf('sourceURL') >= 0 ? 
+      assertEquals(current_source.indexOf('sourceURL') >= 0 ?
                      'myscript.js' : undefined,
                    event_data.script().name());
     }
diff --git a/test/mjsunit/debug-evaluate-recursive.js b/test/mjsunit/debug-evaluate-recursive.js
index 6ee391b..f34943e 100644
--- a/test/mjsunit/debug-evaluate-recursive.js
+++ b/test/mjsunit/debug-evaluate-recursive.js
@@ -110,7 +110,7 @@
     if (event == Debug.DebugEvent.Break)
     {
       break_count++;
-      
+
       // Call functions with break using the FrameMirror directly.
       if (break_count == 1) {
         // First break event evaluates with break enabled.
diff --git a/test/mjsunit/debug-handle.js b/test/mjsunit/debug-handle.js
index 98875ce..1582b9f 100644
--- a/test/mjsunit/debug-handle.js
+++ b/test/mjsunit/debug-handle.js
@@ -72,7 +72,7 @@
 
   // The base part of all lookup requests.
   var base_request = '"seq":0,"type":"request","command":"lookup"'
-  
+
   // Generate request with the supplied arguments.
   var request;
   if (arguments) {
@@ -214,7 +214,7 @@
                  'Handle not in the request: ' + handle);
       count++;
     }
-    assertEquals(count, obj.properties.length, 
+    assertEquals(count, obj.properties.length,
                  'Unexpected number of resolved objects');
 
 
diff --git a/test/mjsunit/debug-listbreakpoints.js b/test/mjsunit/debug-listbreakpoints.js
index de0114f..1d4755f 100644
--- a/test/mjsunit/debug-listbreakpoints.js
+++ b/test/mjsunit/debug-listbreakpoints.js
@@ -39,7 +39,7 @@
 // below.  The test checks for these line numbers.
 
 function g() { // line 40
-  var x = 5; 
+  var x = 5;
   var y = 6;
   var z = 7;
 };
diff --git a/test/mjsunit/debug-references.js b/test/mjsunit/debug-references.js
index ab6c629..763e354 100644
--- a/test/mjsunit/debug-references.js
+++ b/test/mjsunit/debug-references.js
@@ -52,7 +52,7 @@
   } else {
     request = '{' + base_request + '}'
   }
-  
+
   // Process the request and check expectation.
   var response = safeEval(dcp.processDebugJSONRequest(request));
   if (success) {
@@ -88,7 +88,7 @@
     var response = safeEval(dcp.processDebugJSONRequest(evaluate_point));
     assertTrue(response.success, "Evaluation of Point failed");
     var handle = response.body.handle;
-    
+
     // Test some legal references requests.
     testRequest(dcp, '{"handle":' + handle + ',"type":"referencedBy"}', true);
     testRequest(dcp, '{"handle":' + handle + ',"type":"constructedBy"}',
diff --git a/test/mjsunit/debug-return-value.js b/test/mjsunit/debug-return-value.js
index 3982ea9..02d6a7c 100644
--- a/test/mjsunit/debug-return-value.js
+++ b/test/mjsunit/debug-return-value.js
@@ -103,12 +103,12 @@
         // Position at the end of the function.
         assertEquals(debugger_source_position + 50,
         exec_state.frame(0).sourcePosition());
-        
+
         // Just about to return from the function.
         assertTrue(exec_state.frame(0).isAtReturn())
         assertEquals(expected_return_value,
                      exec_state.frame(0).returnValue().value());
-        
+
         // Check the same using the JSON commands.
         var dcp = exec_state.debugCommandProcessor(false);
         var request = '{"seq":0,"type":"request","command":"backtrace"}';
@@ -118,7 +118,7 @@
         assertTrue(frames[0].atReturn);
         assertEquals(expected_return_value,
                      response.lookup(frames[0].returnValue.ref).value);
-        
+
         listener_complete = true;
       }
     }
@@ -132,7 +132,7 @@
 
 // Four steps from the debugger statement in this function will position us at
 // the function return.
-//             0         1         2         3         4         5 
+//             0         1         2         3         4         5
 //             0123456789012345678901234567890123456789012345678901
 
 function f(x) {debugger; if (x) { return 1; } else { return 2; } };
diff --git a/test/mjsunit/debug-stepin-call-function-stub.js b/test/mjsunit/debug-stepin-call-function-stub.js
index c5cf8fd..053b8bf 100644
--- a/test/mjsunit/debug-stepin-call-function-stub.js
+++ b/test/mjsunit/debug-stepin-call-function-stub.js
@@ -62,7 +62,7 @@
 Debug.setListener(listener);
 
 
-function g() { 
+function g() {
    return "s";  // expected line
 }
 
@@ -71,7 +71,7 @@
   var s = 1 +f(10);
 }
 
-function g2() { 
+function g2() {
    return "s2";  // expected line
 }
 
diff --git a/test/mjsunit/debug-stepin-constructor.js b/test/mjsunit/debug-stepin-constructor.js
index 6ee3347..5549814 100644
--- a/test/mjsunit/debug-stepin-constructor.js
+++ b/test/mjsunit/debug-stepin-constructor.js
@@ -38,7 +38,7 @@
     if (exec_state.frameCount() > 1) {
       exec_state.prepareStep(Debug.StepAction.StepIn);
     }
-    
+
     // Test that there is a script.
     assertTrue(typeof(event_data.func().script()) == 'object');
   }
diff --git a/test/mjsunit/delete-in-with.js b/test/mjsunit/delete-in-with.js
index 1efc18d..cbcfe99 100644
--- a/test/mjsunit/delete-in-with.js
+++ b/test/mjsunit/delete-in-with.js
@@ -29,6 +29,6 @@
 // objects from within 'with' statements.
 (function(){
   var tmp = { x: 12 };
-  with (tmp) { assertTrue(delete x); }  
+  with (tmp) { assertTrue(delete x); }
   assertFalse("x" in tmp);
 })();
diff --git a/test/mjsunit/function-source.js b/test/mjsunit/function-source.js
index 7525775..8f2fc22 100644
--- a/test/mjsunit/function-source.js
+++ b/test/mjsunit/function-source.js
@@ -36,7 +36,7 @@
   }
   h();
 }
-  
+
 function g() {
   function h() {
     assertEquals(Debug.scriptSource(f), Debug.scriptSource(h));
diff --git a/test/mjsunit/get-own-property-descriptor.js b/test/mjsunit/get-own-property-descriptor.js
index 79c1fac..abb2420 100644
--- a/test/mjsunit/get-own-property-descriptor.js
+++ b/test/mjsunit/get-own-property-descriptor.js
@@ -27,7 +27,7 @@
 
 // This file only tests very simple descriptors that always have
 // configurable, enumerable, and writable set to true.
-// A range of more elaborate tests are performed in 
+// A range of more elaborate tests are performed in
 // object-define-property.js
 
 function get() { return x; }
diff --git a/test/mjsunit/global-deleted-property-keyed.js b/test/mjsunit/global-deleted-property-keyed.js
index 1a1d3cb..dba3a4d 100644
--- a/test/mjsunit/global-deleted-property-keyed.js
+++ b/test/mjsunit/global-deleted-property-keyed.js
@@ -33,6 +33,6 @@
 var name = "fisk";
 natives[name] = name;
 function foo() { natives[name] + 12; }
-for(var i = 0; i < 3; i++) foo(); 
+for(var i = 0; i < 3; i++) foo();
 delete natives[name];
 for(var i = 0; i < 3; i++) foo();
diff --git a/test/mjsunit/harmony/block-conflicts.js b/test/mjsunit/harmony/block-conflicts.js
new file mode 100644
index 0000000..8d3de6f
--- /dev/null
+++ b/test/mjsunit/harmony/block-conflicts.js
@@ -0,0 +1,126 @@
+// Copyright 2011 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.
+
+// Flags: --harmony-block-scoping
+
+// Test for conflicting variable bindings.
+
+function CheckException(e) {
+  var string = e.toString();
+  assertTrue(string.indexOf("has already been declared") >= 0 ||
+             string.indexOf("redeclaration") >= 0);  return 'Conflict';
+}
+
+
+function TestFunction(s,e) {
+  try {
+    return eval("(function(){" + s + ";return " + e + "})")();
+  } catch (x) {
+    return CheckException(x);
+  }
+}
+
+
+function TestBlock(s,e) {
+  try {
+    return eval("(function(){ if (true) { " + s + "; }; return " + e + "})")();
+  } catch (x) {
+    return CheckException(x);
+  }
+}
+
+function TestAll(expected,s,opt_e) {
+  var e = "";
+  var msg = s;
+  if (opt_e) { e = opt_e; msg += "; " + opt_e; }
+  assertEquals(expected, TestFunction(s,e), "function:'" + msg + "'");
+  assertEquals(expected, TestBlock(s,e), "block:'" + msg + "'");
+}
+
+
+function TestConflict(s) {
+  TestAll('Conflict', s);
+  TestAll('Conflict', 'eval("' + s + '")');
+}
+
+
+function TestNoConflict(s) {
+  TestAll('NoConflict', s, "'NoConflict'");
+  TestAll('NoConflict', 'eval("' + s + '")', "'NoConflict'");
+}
+
+var letbinds = [ "let x",
+                 "let x = 0",
+                 "let x = undefined",
+                 "function x() { }",
+                 "let x = function() {}",
+                 "let x, y",
+                 "let y, x",
+                 ];
+var varbinds = [ "var x",
+                 "var x = 0",
+                 "var x = undefined",
+                 "var x = function() {}",
+                 "var x, y",
+                 "var y, x",
+                 ];
+
+
+for (var l = 0; l < letbinds.length; ++l) {
+  // Test conflicting let/var bindings.
+  for (var v = 0; v < varbinds.length; ++v) {
+    // Same level.
+    TestConflict(letbinds[l] +'; ' + varbinds[v]);
+    TestConflict(varbinds[v] +'; ' + letbinds[l]);
+    // Different level.
+    TestConflict(letbinds[l] +'; {' + varbinds[v] + '; }');
+    TestConflict('{ ' + varbinds[v] +'; }' + letbinds[l]);
+  }
+
+  // Test conflicting let/let bindings.
+  for (var k = 0; k < letbinds.length; ++k) {
+    // Same level.
+    TestConflict(letbinds[l] +'; ' + letbinds[k]);
+    TestConflict(letbinds[k] +'; ' + letbinds[l]);
+    // Different level.
+    TestNoConflict(letbinds[l] +'; { ' + letbinds[k] + '; }');
+    TestNoConflict('{ ' + letbinds[k] +'; } ' + letbinds[l]);
+  }
+
+  // Test conflicting parameter/let bindings.
+  TestConflict('(function (x) { ' + letbinds[l] + '; })()');
+}
+
+// Test conflicting catch/var bindings.
+for (var v = 0; v < varbinds.length; ++v) {
+  TestConflict('try {} catch (x) { ' + varbinds[v] + '; }');
+}
+
+// Test conflicting parameter/var bindings.
+for (var v = 0; v < varbinds.length; ++v) {
+  TestConflict('(function (x) { ' + varbinds[v] + '; })()');
+}
diff --git a/test/mjsunit/harmony/block-let-declaration.js b/test/mjsunit/harmony/block-let-declaration.js
index 19c943f..49b6348 100644
--- a/test/mjsunit/harmony/block-let-declaration.js
+++ b/test/mjsunit/harmony/block-let-declaration.js
@@ -57,11 +57,9 @@
 
 // Unprotected statement
 TestLocalThrows("if (true) let x;", SyntaxError);
-TestLocalThrows("with ({}) let x;", SyntaxError);
 TestLocalThrows("do let x; while (false)", SyntaxError);
 TestLocalThrows("while (false) let x;", SyntaxError);
 
 TestLocalDoesNotThrow("if (true) var x;");
-TestLocalDoesNotThrow("with ({}) var x;");
 TestLocalDoesNotThrow("do var x; while (false)");
 TestLocalDoesNotThrow("while (false) var x;");
diff --git a/test/mjsunit/harmony/debug-blockscopes.js b/test/mjsunit/harmony/debug-blockscopes.js
index e0df71b..d02c9f6 100644
--- a/test/mjsunit/harmony/debug-blockscopes.js
+++ b/test/mjsunit/harmony/debug-blockscopes.js
@@ -202,17 +202,15 @@
 }
 
 listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.Local,
+  CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
-  CheckScopeContent({}, 1, exec_state);
 };
 local_block_1();
 EndTest();
 
 
-// Local scope with a parameter.
+// Simple empty block scope in local scope with a parameter.
 BeginTest("Local 2");
 
 function local_2(a) {
@@ -222,10 +220,9 @@
 }
 
 listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.Local,
+  CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Global], exec_state);
-  CheckScopeContent({a:1}, 1, exec_state);
+  CheckScopeContent({a:1}, 0, exec_state);
 };
 local_2(1);
 EndTest();
@@ -266,6 +263,72 @@
 EndTest();
 
 
+// Single variable in a block scope.
+BeginTest("Local 5");
+
+function local_5(a) {
+  {
+    let x = 5;
+    debugger;
+  }
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({x:5}, 0, exec_state);
+  CheckScopeContent({a:1}, 1, exec_state);
+};
+local_5(1);
+EndTest();
+
+
+// Two variables in a block scope.
+BeginTest("Local 6");
+
+function local_6(a) {
+  {
+    let x = 6;
+    let y = 7;
+    debugger;
+  }
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({x:6,y:7}, 0, exec_state);
+  CheckScopeContent({a:1}, 1, exec_state);
+};
+local_6(1);
+EndTest();
+
+
+// Two variables in a block scope.
+BeginTest("Local 7");
+
+function local_7(a) {
+  {
+    {
+      let x = 8;
+      debugger;
+    }
+  }
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({x:8}, 0, exec_state);
+  CheckScopeContent({a:1}, 1, exec_state);
+};
+local_7(1);
+EndTest();
+
+
 // Single empty with block.
 BeginTest("With block 1");
 
@@ -276,8 +339,7 @@
 }
 
 listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.With,
+  CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.Local,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
@@ -299,16 +361,13 @@
 }
 
 listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.With,
-                   debug.ScopeType.Block,
+  CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.With,
                    debug.ScopeType.Local,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
   CheckScopeContent({}, 1, exec_state);
   CheckScopeContent({}, 2, exec_state);
-  CheckScopeContent({}, 3, exec_state);
 };
 with_block_2();
 EndTest();
@@ -324,12 +383,10 @@
 }
 
 listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.With,
+  CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.Local,
                    debug.ScopeType.Global], exec_state);
-  CheckScopeContent({}, 0, exec_state);
-  CheckScopeContent({a:1,b:2}, 1, exec_state);
+  CheckScopeContent({a:1,b:2}, 0, exec_state);
 };
 with_block_3();
 EndTest();
@@ -347,14 +404,12 @@
 }
 
 listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.Block,
-                   debug.ScopeType.With,
-                   debug.ScopeType.Block,
+  CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.With,
                    debug.ScopeType.Local,
                    debug.ScopeType.Global], exec_state);
-  CheckScopeContent({a:2,b:1}, 1, exec_state);
-  CheckScopeContent({a:1,b:2}, 3, exec_state);
+  CheckScopeContent({a:2,b:1}, 0, exec_state);
+  CheckScopeContent({a:1,b:2}, 1, exec_state);
 };
 with_block_4();
 EndTest();
diff --git a/test/mjsunit/html-string-funcs.js b/test/mjsunit/html-string-funcs.js
index 213b7f3..b640639 100644
--- a/test/mjsunit/html-string-funcs.js
+++ b/test/mjsunit/html-string-funcs.js
@@ -29,7 +29,7 @@
 // HTML.
 function CheckSimple(f, tag) {
   assertEquals('<' + tag + '>foo</' + tag + '>',
-               "foo"[f]().toLowerCase()); 
+               "foo"[f]().toLowerCase());
 };
 var simple = { big: 'big', blink: 'blink', bold: 'b',
                fixed: 'tt', italics: 'i', small: 'small',
diff --git a/test/mjsunit/in.js b/test/mjsunit/in.js
index f98db42..cca6187 100644
--- a/test/mjsunit/in.js
+++ b/test/mjsunit/in.js
@@ -86,7 +86,7 @@
 assertFalse(0 in a);
 assertTrue(1 in a);
 assertFalse(2 in a);
-assertFalse('0' in a); 
+assertFalse('0' in a);
 assertTrue('1' in a);
 assertFalse('2' in a);
 assertTrue('toString' in a, "toString");
diff --git a/test/mjsunit/instanceof.js b/test/mjsunit/instanceof.js
index 01ea426..050ef2d 100644
--- a/test/mjsunit/instanceof.js
+++ b/test/mjsunit/instanceof.js
@@ -60,10 +60,10 @@
 
 function TestExceptions() {
   function F() { }
-  var items = [ 1, new Number(42), 
-                true, 
+  var items = [ 1, new Number(42),
+                true,
                 'string', new String('hest'),
-                {}, [], 
+                {}, [],
                 F, new F(),
                 Object, String ];
 
diff --git a/test/mjsunit/keyed-storage-extend.js b/test/mjsunit/keyed-storage-extend.js
index 04d2f04..d7e157b 100644
--- a/test/mjsunit/keyed-storage-extend.js
+++ b/test/mjsunit/keyed-storage-extend.js
@@ -37,7 +37,7 @@
 }
 
 function GrowKeyed(o) {
-  var names = ['a','b','c','d','e','f']; 
+  var names = ['a','b','c','d','e','f'];
   var i = 0;
   o[names[i++]] = i;
   o[names[i++]] = i;
diff --git a/test/mjsunit/mirror-array.js b/test/mjsunit/mirror-array.js
index eb8f72a..92e3913 100644
--- a/test/mjsunit/mirror-array.js
+++ b/test/mjsunit/mirror-array.js
@@ -64,7 +64,7 @@
   assertTrue(mirror.protoObject() instanceof debug.Mirror, 'Unexpected mirror hierachy');
   assertTrue(mirror.prototypeObject() instanceof debug.Mirror, 'Unexpected mirror hierachy');
   assertEquals(mirror.length(), a.length, "Length mismatch");
-  
+
   var indexedProperties = mirror.indexedPropertiesFromRange();
   assertEquals(indexedProperties.length, a.length);
   for (var i = 0; i < indexedProperties.length; i++) {
@@ -110,7 +110,7 @@
       var found = false;
       for (var j = 0; j < fromJSON.properties.length; j++) {
         if (names[i] == fromJSON.properties[j].name) {
-          found = true; 
+          found = true;
         }
       }
       assertTrue(found, names[i])
diff --git a/test/mjsunit/mirror-function.js b/test/mjsunit/mirror-function.js
index 58aee3d..cda815d 100644
--- a/test/mjsunit/mirror-function.js
+++ b/test/mjsunit/mirror-function.js
@@ -65,7 +65,7 @@
   assertTrue(mirror.constructorFunction() instanceof debug.ObjectMirror);
   assertTrue(mirror.protoObject() instanceof debug.Mirror);
   assertTrue(mirror.prototypeObject() instanceof debug.Mirror);
-  
+
   // Test text representation
   assertEquals(f.toString(), mirror.toText());
 
diff --git a/test/mjsunit/mirror-script.js b/test/mjsunit/mirror-script.js
index 7156170..1d64ac2 100644
--- a/test/mjsunit/mirror-script.js
+++ b/test/mjsunit/mirror-script.js
@@ -62,7 +62,7 @@
   if (eval_from_line) {
     assertEquals(eval_from_line,  mirror.evalFromLocation().line);
   }
-  
+
   // Parse JSON representation and check.
   var fromJSON = JSON.parse(json);
   assertEquals('script', fromJSON.type);
diff --git a/test/mjsunit/mirror-unresolved-function.js b/test/mjsunit/mirror-unresolved-function.js
index c1fe4a3..46f22a0 100644
--- a/test/mjsunit/mirror-unresolved-function.js
+++ b/test/mjsunit/mirror-unresolved-function.js
@@ -64,7 +64,7 @@
 assertEquals('undefined', mirror.constructorFunction().type());
 assertEquals('undefined', mirror.protoObject().type());
 assertEquals('undefined', mirror.prototypeObject().type());
-  
+
 // Parse JSON representation of unresolved functions and check.
 var fromJSON = eval('(' + json + ')');
 assertEquals('function', fromJSON.type, 'Unexpected mirror type in JSON');
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index b7b0c77..027da58 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -115,6 +115,9 @@
 
 ##############################################################################
 [ $arch == mips ]
+# Run those tests, but expect them to time out.
+array-sort: PASS || TIMEOUT
+mirror-object: PASS || TIMEOUT
 
 # Skip long-running tests.
 compiler/alloc-number: SKIP
@@ -141,8 +144,11 @@
 regress/regress-create-exception: SKIP
 regress/regress-3218915: SKIP
 regress/regress-3247124: SKIP
+regress/regress-1132: SKIP
+regress/regress-1257: SKIP
+regress/regress-91008: SKIP
 
-
+##############################################################################
 [ $isolates ]
 # d8-os writes temporary files that might interfer with each other when running
 # in multible threads. Skip this if running with isolates testing.
diff --git a/test/mjsunit/no-semicolon.js b/test/mjsunit/no-semicolon.js
index fa6ccba..273ec4b 100644
--- a/test/mjsunit/no-semicolon.js
+++ b/test/mjsunit/no-semicolon.js
@@ -30,7 +30,7 @@
 
 function f() { return }
 
-function g() { 
+function g() {
   return
     4;
 }
@@ -42,4 +42,4 @@
 assertEquals(0, i);
 
 for (var i = 0; i < 10; i++) { continue }
-assertEquals(10, i);
\ No newline at end of file
+assertEquals(10, i);
diff --git a/test/mjsunit/object-define-properties.js b/test/mjsunit/object-define-properties.js
index 6b3725b..128df69 100644
--- a/test/mjsunit/object-define-properties.js
+++ b/test/mjsunit/object-define-properties.js
@@ -26,7 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Tests the Object.defineProperties method - ES 15.2.3.7
-// Note that the internal DefineOwnProperty method is tested through 
+// Note that the internal DefineOwnProperty method is tested through
 // object-define-property.js, this file only contains tests specific for
 // Object.defineProperties. Also note that object-create.js contains
 // a range of indirect tests on this method since Object.create uses
diff --git a/test/mjsunit/object-literal-conversions.js b/test/mjsunit/object-literal-conversions.js
index 8540d93..742f814 100644
--- a/test/mjsunit/object-literal-conversions.js
+++ b/test/mjsunit/object-literal-conversions.js
@@ -43,4 +43,4 @@
 
 assertEquals(7, test5[13]);
 assertEquals(7, test6[17.31]);
-  
\ No newline at end of file
+
diff --git a/test/mjsunit/object-literal-overwrite.js b/test/mjsunit/object-literal-overwrite.js
index 5c58a2d..5a3584d 100644
--- a/test/mjsunit/object-literal-overwrite.js
+++ b/test/mjsunit/object-literal-overwrite.js
@@ -79,7 +79,7 @@
 // Test for the classic code generator.
 
 function fun(x) {
-  var inner = { j: function(x) { return x; }, j: 7 }; 
+  var inner = { j: function(x) { return x; }, j: 7 };
   return inner.j;
 }
 
@@ -115,4 +115,4 @@
 
 var y = fun3();
 assertEquals(7, y);
-assertEquals(3, glob3);
\ No newline at end of file
+assertEquals(3, glob3);
diff --git a/test/mjsunit/object-prevent-extensions.js b/test/mjsunit/object-prevent-extensions.js
index dc32342..322a2cb 100644
--- a/test/mjsunit/object-prevent-extensions.js
+++ b/test/mjsunit/object-prevent-extensions.js
@@ -33,7 +33,7 @@
 assertTrue(Object.isExtensible(obj1));
 Object.preventExtensions(obj1);
 
-// Make sure the is_extensible flag is set. 
+// Make sure the is_extensible flag is set.
 assertFalse(Object.isExtensible(obj1));
 obj1.x = 42;
 assertEquals(undefined, obj1.x);
diff --git a/test/mjsunit/parse-int-float.js b/test/mjsunit/parse-int-float.js
index a4f09df..2e4f648 100644
--- a/test/mjsunit/parse-int-float.js
+++ b/test/mjsunit/parse-int-float.js
@@ -100,4 +100,17 @@
 assertEquals(Infinity, parseFloat(1/0), "parseFloat Infinity");
 assertEquals(-Infinity, parseFloat(-1/0), "parseFloat -Infinity");
 
+var state;
+var throwingRadix = { valueOf: function() { state = "throwingRadix"; throw null; } };
+var throwingString = { toString: function() { state = "throwingString"; throw null; } };
+state = null;
+try { parseInt('123', throwingRadix); } catch (e) {}
+assertEquals(state, "throwingRadix");
 
+state = null;
+try { parseInt(throwingString, 10); } catch (e) {}
+assertEquals(state, "throwingString");
+
+state = null;
+try { parseInt(throwingString, throwingRadix); } catch (e) {}
+assertEquals(state, "throwingString");
diff --git a/test/mjsunit/regress/regress-1081309.js b/test/mjsunit/regress/regress-1081309.js
index 009ede1..5a6c524 100644
--- a/test/mjsunit/regress/regress-1081309.js
+++ b/test/mjsunit/regress/regress-1081309.js
@@ -67,7 +67,7 @@
     // The expected backtrace is
     // 1: g
     // 0: [anonymous]
-    
+
     // Get the debug command processor.
     var dcp = exec_state.debugCommandProcessor(false);
 
diff --git a/test/mjsunit/regress/regress-1092.js b/test/mjsunit/regress/regress-1092.js
index 0b29231..00422cb 100644
--- a/test/mjsunit/regress/regress-1092.js
+++ b/test/mjsunit/regress/regress-1092.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Test that CodeGenerator::EmitKeyedPropertyAssignment for the start 
+// Test that CodeGenerator::EmitKeyedPropertyAssignment for the start
 // of an initialization block doesn't normalize the properties of the
 // JSGlobalProxy.
 this.w = 0;
diff --git a/test/mjsunit/regress/regress-1110.js b/test/mjsunit/regress/regress-1110.js
index 204a87b..43b8d77 100644
--- a/test/mjsunit/regress/regress-1110.js
+++ b/test/mjsunit/regress/regress-1110.js
@@ -29,7 +29,7 @@
 
 try {
   function Crash() { continue;if (Crash) {
-    } } 
+    } }
   Crash();
   assertTrue(false);
 } catch (e) {
diff --git a/test/mjsunit/regress/regress-1213575.js b/test/mjsunit/regress/regress-1213575.js
index 0c3dcc2..9d82064 100644
--- a/test/mjsunit/regress/regress-1213575.js
+++ b/test/mjsunit/regress/regress-1213575.js
@@ -33,7 +33,7 @@
 
 var caught = false;
 try {
-  eval('const x'); 
+  eval('const x');
 } catch(e) {
   assertTrue(e instanceof TypeError);
   caught = true;
diff --git a/test/mjsunit/regress/regress-1548.js b/test/mjsunit/regress/regress-1548.js
new file mode 100644
index 0000000..074007b
--- /dev/null
+++ b/test/mjsunit/regress/regress-1548.js
@@ -0,0 +1,48 @@
+// Copyright 2011 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.
+
+// Test that the caller and arguments objects are not available on native
+// functions.
+
+function testfn(f) { return [1].map(f)[0]; }
+function foo() { return [].map.caller; }
+assertEquals(null, testfn(foo));
+
+// Try to delete the caller property (to make sure that we can't get to the
+// caller accessor on the prototype.
+delete Array.prototype.map.caller;
+assertEquals(null, testfn(foo));
+
+// Redo tests with arguments object.
+function testarguments(f) { return [1].map(f)[0]; }
+function bar() { return [].map.arguments; }
+assertEquals(null, testfn(bar));
+
+// Try to delete the arguments property (to make sure that we can't get to the
+// caller accessor on the prototype.
+delete Array.prototype.map.arguments;
+assertEquals(null, testarguments(bar));
diff --git a/test/mjsunit/regress/regress-1647.js b/test/mjsunit/regress/regress-1647.js
new file mode 100644
index 0000000..a6afcc0
--- /dev/null
+++ b/test/mjsunit/regress/regress-1647.js
@@ -0,0 +1,43 @@
+// Copyright 2011 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.
+
+// Flags: --allow-natives-syntax
+
+// Test for correct deoptimization in named function expressions.
+
+var t = { foo: function() {} };
+
+var f = (function bar() {
+ t.foo();
+ assertEquals("function", typeof bar);
+});
+
+for (var i = 0; i < 10; i++) f();
+%OptimizeFunctionOnNextCall(f);
+t.number = 2;
+f();
+
diff --git a/test/mjsunit/regress/regress-1650.js b/test/mjsunit/regress/regress-1650.js
new file mode 100644
index 0000000..fb6a178
--- /dev/null
+++ b/test/mjsunit/regress/regress-1650.js
@@ -0,0 +1,60 @@
+// Copyright 2011 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.
+
+// Flags: --allow-natives-syntax
+
+function g(f) { return f.call.apply(f.bind, arguments); }
+
+var x = new Object;
+
+function t() { }
+
+g(t, x);
+g(t, x);
+g(t, x);
+%OptimizeFunctionOnNextCall(g);
+
+function Fake() {}
+
+var fakeCallInvoked = false;
+
+Fake.prototype.call = function () {
+  assertSame(Fake.prototype.bind, this);
+  assertEquals(2, arguments.length);
+  assertSame(fake, arguments[0]);
+  assertSame(x, arguments[1]);
+  fakeCallInvoked = true;
+};
+
+Fake.prototype.bind = function () {
+};
+
+var fake = new Fake;
+
+g(fake, x);
+
+assertTrue(fakeCallInvoked);
diff --git a/test/mjsunit/regress/regress-1919169.js b/test/mjsunit/regress/regress-1919169.js
index 774f265..a732312 100644
--- a/test/mjsunit/regress/regress-1919169.js
+++ b/test/mjsunit/regress/regress-1919169.js
@@ -30,7 +30,7 @@
  var s2 = "s2";
  for (var i = 0; i < 2; i++) {
    // Crashes in round i==1 with IllegalAccess in %StringAdd(x,y)
-   var res = 1 + s2;  
+   var res = 1 + s2;
    s2 = 2;
  }
 }
diff --git a/test/mjsunit/regress/regress-20070207.js b/test/mjsunit/regress/regress-20070207.js
index e90b2ec..b7f7a5c 100644
--- a/test/mjsunit/regress/regress-20070207.js
+++ b/test/mjsunit/regress/regress-20070207.js
@@ -26,7 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // The following regression test illustrates a problem in using the
-// value of setting a property in the arguments object. 
+// value of setting a property in the arguments object.
 
 function f(s) {
   arguments.length;
diff --git a/test/mjsunit/regress/regress-269.js b/test/mjsunit/regress/regress-269.js
index 49b24c0..ce165e0 100644
--- a/test/mjsunit/regress/regress-269.js
+++ b/test/mjsunit/regress/regress-269.js
@@ -40,10 +40,10 @@
 
 function g() {
 }
- 
+
 function f() {
   debugger;
   g.apply(null, ['']);
 }
 
-f()
\ No newline at end of file
+f()
diff --git a/test/mjsunit/regress/regress-619.js b/test/mjsunit/regress/regress-619.js
index 24bdbc1..4d3e66b 100644
--- a/test/mjsunit/regress/regress-619.js
+++ b/test/mjsunit/regress/regress-619.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Tests that Object.defineProperty works correctly on array indices. 
+// Tests that Object.defineProperty works correctly on array indices.
 // Please see http://code.google.com/p/v8/issues/detail?id=619 for details.
 
 var obj = {};
diff --git a/test/mjsunit/regress/regress-678525.js b/test/mjsunit/regress/regress-678525.js
index 5ff9c3d..11eaf74 100644
--- a/test/mjsunit/regress/regress-678525.js
+++ b/test/mjsunit/regress/regress-678525.js
@@ -36,16 +36,16 @@
 assertEquals(56, '\8'.charCodeAt(0));
 
 assertEquals('\010', '\10');
-assertEquals('\011', '\11');    
+assertEquals('\011', '\11');
 assertEquals('\012', '\12');
 assertEquals('\013', '\13');
 assertEquals('\014', '\14');
 assertEquals('\015', '\15');
 assertEquals('\016', '\16');
 assertEquals('\017', '\17');
-    
+
 assertEquals('\020', '\20');
-assertEquals('\021', '\21');    
+assertEquals('\021', '\21');
 assertEquals('\022', '\22');
 assertEquals('\023', '\23');
 assertEquals('\024', '\24');
@@ -56,4 +56,4 @@
 assertEquals(73,  '\111'.charCodeAt(0));
 assertEquals(105, '\151'.charCodeAt(0));
 
-    
+
diff --git a/test/mjsunit/regress/regress-696.js b/test/mjsunit/regress/regress-696.js
index 21977e1..e443c42 100644
--- a/test/mjsunit/regress/regress-696.js
+++ b/test/mjsunit/regress/regress-696.js
@@ -28,7 +28,7 @@
 // See: http://code.google.com/p/v8/issues/detail?id=696
 // Because of the change in dateparser in revision 4557 to support time
 // only strings in Date.parse we also misleadingly supported strings with non
-// leading numbers. 
+// leading numbers.
 
 assertTrue(isNaN(Date.parse('x')));
 assertTrue(isNaN(Date.parse('1x')));
diff --git a/test/mjsunit/regress/regress-720.js b/test/mjsunit/regress/regress-720.js
index 97e1284..267b32d 100644
--- a/test/mjsunit/regress/regress-720.js
+++ b/test/mjsunit/regress/regress-720.js
@@ -27,7 +27,7 @@
 
 // This regression test is used to ensure that Object.defineProperty
 // keeps the existing value of the writable flag if none is given
-// in the provided descriptor. 
+// in the provided descriptor.
 // See: http://code.google.com/p/v8/issues/detail?id=720
 
 var o = {x: 10};
diff --git a/test/mjsunit/regress/regress-747.js b/test/mjsunit/regress/regress-747.js
index 6fcc000..648c366 100644
--- a/test/mjsunit/regress/regress-747.js
+++ b/test/mjsunit/regress/regress-747.js
@@ -40,7 +40,7 @@
   callEval();
 } catch (e) {
   assertUnreachable();
-} 
+}
 
 gc();
 gc();
@@ -53,4 +53,4 @@
   callEval();
 } catch (e) {
   assertUnreachable();
-} 
+}
diff --git a/test/mjsunit/regress/regress-760-1.js b/test/mjsunit/regress/regress-760-1.js
index 2e0cee5..081c993 100644
--- a/test/mjsunit/regress/regress-760-1.js
+++ b/test/mjsunit/regress/regress-760-1.js
@@ -26,7 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Check that when valueOf for a String object is overwritten it is called and
-// the result used when that object is added with a string.  
+// the result used when that object is added with a string.
 
 // See: http://code.google.com/p/v8/issues/detail?id=760
 
diff --git a/test/mjsunit/regress/regress-760-2.js b/test/mjsunit/regress/regress-760-2.js
index 1b1cbfe..549ed4e 100644
--- a/test/mjsunit/regress/regress-760-2.js
+++ b/test/mjsunit/regress/regress-760-2.js
@@ -26,7 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Check that when valueOf for a String object is overwritten it is called and
-// the result used when that object is added with a string.  
+// the result used when that object is added with a string.
 
 // See: http://code.google.com/p/v8/issues/detail?id=760
 
diff --git a/test/mjsunit/regress/regress-798.js b/test/mjsunit/regress/regress-798.js
index ffee5da..182eb4d 100644
--- a/test/mjsunit/regress/regress-798.js
+++ b/test/mjsunit/regress/regress-798.js
@@ -32,7 +32,7 @@
   try {
     y.x = 40;
   } catch (e) {
-    assertEquals(3, e.stack.split('\n').length); 
+    assertEquals(3, e.stack.split('\n').length);
   }
   return 40;
 });
@@ -41,7 +41,7 @@
   try {
     y.x = 40;
   } catch(e) {
-    assertEquals(3, e.stack.split('\n').length); 
+    assertEquals(3, e.stack.split('\n').length);
   }
 });
 
@@ -50,7 +50,7 @@
   try {
     y.x = 30;
   } catch (e) {
-    assertEquals(3, e.stack.split('\n').length); 
+    assertEquals(3, e.stack.split('\n').length);
   }
   return 30;
 }
@@ -59,7 +59,7 @@
   try {
     y.x = 30;
   } catch(e) {
-    assertEquals(3, e.stack.split('\n').length); 
+    assertEquals(3, e.stack.split('\n').length);
   }
 }
 
@@ -72,7 +72,7 @@
     try {
       y.x = 40;
     } catch (e) {
-      assertEquals(3, e.stack.split('\n').length); 
+      assertEquals(3, e.stack.split('\n').length);
     }
     return 40;
   },
@@ -80,7 +80,7 @@
     try {
       y.x = 40;
     } catch(e) {
-      assertEquals(3, e.stack.split('\n').length); 
+      assertEquals(3, e.stack.split('\n').length);
     }
   }
 }
@@ -88,7 +88,7 @@
 Object.defineProperty(x, 'c', descriptor)
 
 // Check that the stack for an exception in a getter and setter produce the
-// expected stack height.   
+// expected stack height.
 x.a;
 x.b;
 x.c;
diff --git a/test/mjsunit/regress/regress-918.js b/test/mjsunit/regress/regress-918.js
index 4b6ddba..871e9d9 100644
--- a/test/mjsunit/regress/regress-918.js
+++ b/test/mjsunit/regress/regress-918.js
@@ -28,6 +28,6 @@
 // Parser should not accept parentheses around labels.
 // See http://code.google.com/p/v8/issues/detail?id=918
 
-// The label was parsed as an expression and then tested for being a 
+// The label was parsed as an expression and then tested for being a
 // single identifier. This threw away the parentheses.
 assertThrows("(label):42;");
diff --git a/test/mjsunit/regress/regress-925537.js b/test/mjsunit/regress/regress-925537.js
index 11582ea..d50c568 100644
--- a/test/mjsunit/regress/regress-925537.js
+++ b/test/mjsunit/regress/regress-925537.js
@@ -28,8 +28,8 @@
 function assertClose(expected, actual) {
   var delta = 0.00001;
   if (Math.abs(expected - actual) > delta) {
-    print('Failure: Expected <' + actual + '> to be close to <' + 
-          expected + '>');    
+    print('Failure: Expected <' + actual + '> to be close to <' +
+          expected + '>');
   }
 }
 
diff --git a/test/mjsunit/regress/regress-937896.js b/test/mjsunit/regress/regress-937896.js
index e8e5ef2..e7831da 100644
--- a/test/mjsunit/regress/regress-937896.js
+++ b/test/mjsunit/regress/regress-937896.js
@@ -41,7 +41,7 @@
       }
     }
   } catch (e) {
-    // Empty. 
+    // Empty.
   }
   return 42;
 }
diff --git a/test/mjsunit/regress/regress-fundecl.js b/test/mjsunit/regress/regress-fundecl.js
new file mode 100644
index 0000000..fddb589
--- /dev/null
+++ b/test/mjsunit/regress/regress-fundecl.js
@@ -0,0 +1,44 @@
+// Copyright 2011 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.
+
+// Flags: --allow-natives-syntax
+
+// Test hoisting of function declarations in the optimizing
+// compiler in case of deoptimization.
+
+function h(a, b) {
+  var r = a + b;
+  function X() { return 42; }
+  return r + X();
+}
+
+for (var i = 0; i < 5; i++) h(1,2);
+
+%OptimizeFunctionOnNextCall(h);
+
+assertEquals(45, h(1,2));
+assertEquals("foo742", h("foo", 7));
diff --git a/test/mjsunit/setter-on-constructor-prototype.js b/test/mjsunit/setter-on-constructor-prototype.js
index d5718f9..a74f7da 100644
--- a/test/mjsunit/setter-on-constructor-prototype.js
+++ b/test/mjsunit/setter-on-constructor-prototype.js
@@ -35,14 +35,14 @@
   if (ensure_fast_case) {
     %ToFastProperties(C1.prototype);
   }
-  
+
   for (var i = 0; i < 10; i++) {
     var c1 = new C1();
     assertEquals("undefined", typeof c1.x);
     assertEquals(23, c1.y);
   }
-  
-  
+
+
   function C2() {
     this.x = 23;
   };
@@ -51,14 +51,14 @@
   if (ensure_fast_case) {
     %ToFastProperties(C2.prototype.__proto__)
   }
-  
+
   for (var i = 0; i < 10; i++) {
     var c2 = new C2();
     assertEquals("undefined", typeof c2.x);
     assertEquals(23, c2.y);
   }
-  
-  
+
+
   function C3() {
     this.x = 23;
   };
@@ -67,14 +67,14 @@
   if (ensure_fast_case) {
     %ToFastProperties(C3.prototype);
   }
-  
+
   for (var i = 0; i < 10; i++) {
     var c3 = new C3();
     assertEquals("undefined", typeof c3.x);
     assertEquals(23, c3.y);
   }
-  
-  
+
+
   function C4() {
     this.x = 23;
   };
@@ -84,14 +84,14 @@
   if (ensure_fast_case) {
     %ToFastProperties(C4.prototype.__proto__);
   }
-  
+
   for (var i = 0; i < 10; i++) {
     var c4 = new C4();
     assertEquals("undefined", typeof c4.x);
     assertEquals(23, c4.y);
   }
-  
-  
+
+
   function D() {
     this.x = 23;
   };
@@ -99,7 +99,7 @@
   if (ensure_fast_case) {
     %ToFastProperties(D.prototype);
   }
-  
+
   for (var i = 0; i < 10; i++) {
     var d = new D();
     assertEquals(23, d.x);
diff --git a/test/mjsunit/string-compare-alignment.js b/test/mjsunit/string-compare-alignment.js
index a291417..0ae8eb7 100644
--- a/test/mjsunit/string-compare-alignment.js
+++ b/test/mjsunit/string-compare-alignment.js
@@ -29,8 +29,9 @@
 // This situation can arise with sliced strings.  This tests for an ARM bug
 // that was fixed in r554.
 
-var base = "Now is the time for all good men to come to the aid of the party. " + 
-           "Now is the time for all good men to come to the aid of the party."
+var base =
+    "Now is the time for all good men to come to the aid of the party. " +
+    "Now is the time for all good men to come to the aid of the party."
 var s1 = base.substring(0, 64);
 var s2 = base.substring(66, 130);
 
diff --git a/test/mjsunit/string-indexof-1.js b/test/mjsunit/string-indexof-1.js
index c5ae4b8..db3623f 100644
--- a/test/mjsunit/string-indexof-1.js
+++ b/test/mjsunit/string-indexof-1.js
@@ -63,7 +63,7 @@
 assertEquals(2, twoByteString.indexOf("\u03a3"), "First Sigma");
 assertEquals(3, twoByteString.indexOf("\u03a3",3), "Second Sigma");
 assertEquals(4, twoByteString.indexOf("\u0395"), "Epsilon");
-assertEquals(-1, twoByteString.indexOf("\u0392"), "Not beta");  
+assertEquals(-1, twoByteString.indexOf("\u0392"), "Not beta");
 
 // Test multi-char pattern
 assertEquals(0, twoByteString.indexOf("\u039a\u0391"), "lambda Alpha");
@@ -71,7 +71,7 @@
 assertEquals(2, twoByteString.indexOf("\u03a3\u03a3"), "Sigma Sigma");
 assertEquals(3, twoByteString.indexOf("\u03a3\u0395"), "Sigma Epsilon");
 
-assertEquals(-1, twoByteString.indexOf("\u0391\u03a3\u0395"), 
+assertEquals(-1, twoByteString.indexOf("\u0391\u03a3\u0395"),
     "Not Alpha Sigma Epsilon");
 
 //single char pattern
diff --git a/test/mjsunit/string-indexof-2.js b/test/mjsunit/string-indexof-2.js
index a7c3f60..48db84d 100644
--- a/test/mjsunit/string-indexof-2.js
+++ b/test/mjsunit/string-indexof-2.js
@@ -57,10 +57,10 @@
     var index = -1;
     do {
       index = lipsum.indexOf(substring, index + 1);
-      assertTrue(index != -1, 
+      assertTrue(index != -1,
                  "Lipsum substring " + i + ".." + (i + len-1) + " not found");
-      assertEquals(lipsum.substring(index, index + len), substring, 
-          "Wrong lipsum substring found: " + i + ".." + (i + len - 1) + "/" + 
+      assertEquals(lipsum.substring(index, index + len), substring,
+          "Wrong lipsum substring found: " + i + ".." + (i + len - 1) + "/" +
               index + ".." + (index + len - 1));
     } while (index >= 0 && index < i);
     assertEquals(i, index, "Lipsum match at " + i + ".." + (i + len - 1));
diff --git a/test/mjsunit/string-slices.js b/test/mjsunit/string-slices.js
index f629ca9..8cc1f81 100755
--- a/test/mjsunit/string-slices.js
+++ b/test/mjsunit/string-slices.js
@@ -57,7 +57,7 @@
 assertEquals('abc', s.substr(-100, 3));
 assertEquals(s1, s.substr(-s.length + 1));
 
-// assertEquals('', s.substr(0, void 0)); // smjs and rhino 
+// assertEquals('', s.substr(0, void 0)); // smjs and rhino
 assertEquals('abcdefghijklmn', s.substr(0, void 0));  // kjs and v8
 assertEquals('', s.substr(0, null));
 assertEquals(s, s.substr(0, String(s.length)));
@@ -196,4 +196,4 @@
 assertEquals(a.slice(1,-1), b);
 externalizeString(a);
 assertEquals(a.slice(1,-1), b);
-*/
\ No newline at end of file
+*/
diff --git a/test/mjsunit/string-split.js b/test/mjsunit/string-split.js
index bc50945..d8412f0 100644
--- a/test/mjsunit/string-split.js
+++ b/test/mjsunit/string-split.js
@@ -68,13 +68,13 @@
 
 
 /* "ab".split(/((?=.))/)
- * 
+ *
  * KJS:   ,a,,b
  * SM:    a,,b,
  * IE:    a,b
  * Opera: a,,b
  * V8:    a,,b
- * 
+ *
  * Opera seems to have this right.  The others make no sense.
  */
 assertArrayEquals(["a", "", "b"], "ab".split(/((?=.))/));
diff --git a/test/mjsunit/substr.js b/test/mjsunit/substr.js
index cffaf94..cab8b1b 100755
--- a/test/mjsunit/substr.js
+++ b/test/mjsunit/substr.js
@@ -55,7 +55,7 @@
 assertEquals('abc', s.substr(-100, 3));
 assertEquals(s1, s.substr(-s.length + 1));
 
-// assertEquals('', s.substr(0, void 0)); // smjs and rhino 
+// assertEquals('', s.substr(0, void 0)); // smjs and rhino
 assertEquals('abcdefghijklmn', s.substr(0, void 0));  // kjs and v8
 assertEquals('', s.substr(0, null));
 assertEquals(s, s.substr(0, String(s.length)));
diff --git a/test/mjsunit/this-property-assignment.js b/test/mjsunit/this-property-assignment.js
index c681999..54c6537 100644
--- a/test/mjsunit/this-property-assignment.js
+++ b/test/mjsunit/this-property-assignment.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Tests the handling of multiple assignments to the same property in a 
+// Tests the handling of multiple assignments to the same property in a
 // constructor that only has simple this property assignments.
 
 function Node() {
diff --git a/test/mjsunit/try.js b/test/mjsunit/try.js
index 794860a..86afdf7 100644
--- a/test/mjsunit/try.js
+++ b/test/mjsunit/try.js
@@ -250,7 +250,7 @@
     } catch (o) {
       x--;
     }
-  } 
+  }
   return x;
 }
 
@@ -274,7 +274,7 @@
       x--;
     }
     x--; // should not happen
-  } 
+  }
   return x;
 }
 
diff --git a/test/mjsunit/unicode-test.js b/test/mjsunit/unicode-test.js
index 59a684e..66a029a 100644
--- a/test/mjsunit/unicode-test.js
+++ b/test/mjsunit/unicode-test.js
@@ -807,7 +807,7 @@
 "    * Васильев Л.С. Древний Китай: в 3 т. Т. 3. Период Чжаньго (V–III вв. до н.э.). М.: Восточная литература, 2006. ISBN 502018103X\n" +
 "    * Непомнин О.Е. История Китая: Эпоха Цин. XVII – начало XX века. М.: Восточная литература, 2005. ISBN 5020184004\n";
 
-var devanagari = 
+var devanagari =
 "भारत\n" +
 "विकिपीडिया, एक मुक्त ज्ञानकोष से\n" +
 "Jump to: navigation, search\n" +
@@ -1417,7 +1417,7 @@
 "There are many words of French origin in English, such as competition, art, table, publicity, police, role, routine, machine, force, and many others that have been and are being anglicised; they are now pronounced according to English rules of phonology, rather than French. A large portion of English vocabulary is of French or Oïl language origin, most derived from, or transmitted via, the Anglo-Norman spoken by the upper classes in England for several hundred years after the Norman Conquest.\n";
 
 
-var greek = 
+var greek =
 "Ελλάδα\n" +
 "Από τη Βικιπαίδεια, την ελεύθερη εγκυκλοπαίδεια\n" +
 "Ελληνική Δημοκρατία\n" +
diff --git a/test/mjsunit/value-wrapper.js b/test/mjsunit/value-wrapper.js
index 88330b4..76e200f 100644
--- a/test/mjsunit/value-wrapper.js
+++ b/test/mjsunit/value-wrapper.js
@@ -39,7 +39,7 @@
     assertEquals('object', (42).TypeOfThis());
     assertEquals('object', (3.14).TypeOfThis());
   }
-  
+
   for (var i = 0; i < 10; i++) {
     assertEquals('object', 'xxx'['TypeOfThis']());
     assertEquals('object', true['TypeOfThis']());
@@ -47,11 +47,11 @@
     assertEquals('object', (42)['TypeOfThis']());
     assertEquals('object', (3.14)['TypeOfThis']());
   }
-  
+
   function CallTypeOfThis(obj) {
     assertEquals('object', obj.TypeOfThis());
   }
-  
+
   for (var i = 0; i < 10; i++) {
     CallTypeOfThis('xxx');
     CallTypeOfThis(true);
@@ -59,7 +59,7 @@
     CallTypeOfThis(42);
     CallTypeOfThis(3.14);
   }
-  
+
   function TestWithWith(obj) {
     with (obj) {
       for (var i = 0; i < 10; i++) {
@@ -67,13 +67,13 @@
       }
     }
   }
-  
+
   TestWithWith('xxx');
   TestWithWith(true);
   TestWithWith(false);
   TestWithWith(42);
   TestWithWith(3.14);
-  
+
   for (var i = 0; i < 10; i++) {
     assertEquals('object', true[7]());
     assertEquals('object', false[7]());
@@ -100,7 +100,7 @@
 
 function TypeOfThis() { return typeof this; }
 
-// Test with normal setup of prototype. 
+// Test with normal setup of prototype.
 String.prototype.TypeOfThis = TypeOfThis;
 Boolean.prototype.TypeOfThis = TypeOfThis;
 Number.prototype.TypeOfThis = TypeOfThis;
diff --git a/test/mozilla/mozilla.status b/test/mozilla/mozilla.status
index f6d6925..3a27130 100644
--- a/test/mozilla/mozilla.status
+++ b/test/mozilla/mozilla.status
@@ -201,6 +201,10 @@
 ecma_3/RegExp/regress-85721: PASS || FAIL if $mode == debug
 
 
+# Test that assumes specific execution time, flaky in debug mode.
+js1_5/Array/regress-101964: PASS || FAIL if $mode == debug
+
+
 ##################### INCOMPATIBLE TESTS #####################
 
 # This section is for tests that fail in both V8 and JSC.  Thus they
@@ -245,7 +249,7 @@
 # toExponential argument restricted to range 0..20 in JSC/V8
 ecma_3/Number/15.7.4.6-1: FAIL_OK
 
-#:=== RegExp:=== 
+#:=== RegExp:===
 # We don't match the syntax error message of Mozilla for invalid
 # RegExp flags.
 ecma_3/RegExp/15.10.4.1-6: FAIL_OK
@@ -578,7 +582,7 @@
 js1_5/Regress/regress-417893: FAIL_OK
 
 
-# Unsupported use of "[]" as function parameter. We match JSC. 
+# Unsupported use of "[]" as function parameter. We match JSC.
 js1_5/Regress/regress-416737-01: FAIL_OK
 js1_5/Regress/regress-416737-02: FAIL_OK
 
diff --git a/tools/gdb-v8-support.py b/tools/gdb-v8-support.py
index 0aa1d49..9cc046c 100644
--- a/tools/gdb-v8-support.py
+++ b/tools/gdb-v8-support.py
@@ -138,7 +138,7 @@
   else:
     return '?'
 
-  
+
 def v8_get_value(vstring):
   v = gdb.parse_and_eval(vstring)
   return v8_to_int(v)
diff --git a/tools/presubmit.py b/tools/presubmit.py
index c191fc7..50d2620 100755
--- a/tools/presubmit.py
+++ b/tools/presubmit.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2008 the V8 project authors. All rights reserved.
+# Copyright 2011 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,6 +42,7 @@
 import re
 import sys
 import subprocess
+from subprocess import PIPE
 
 # Disabled LINT rules and reason.
 # build/include_what_you_use: Started giving false positives for variables
@@ -88,7 +89,6 @@
 whitespace/braces
 whitespace/comma
 whitespace/comments
-whitespace/end_of_line
 whitespace/ending_newline
 whitespace/indent
 whitespace/labels
@@ -231,11 +231,29 @@
 
 class SourceProcessor(SourceFileProcessor):
   """
-  Check that all files include a copyright notice.
+  Check that all files include a copyright notice and no trailing whitespaces.
   """
 
   RELEVANT_EXTENSIONS = ['.js', '.cc', '.h', '.py', '.c', 'SConscript',
-      'SConstruct', '.status']
+      'SConstruct', '.status', '.gyp', '.gypi']
+
+  # Overwriting the one in the parent class.
+  def FindFilesIn(self, path):
+    if os.path.exists(path+'/.git'):
+      output = subprocess.Popen('git ls-files --full-name',
+                                stdout=PIPE, cwd=path, shell=True)
+      result = []
+      for file in output.stdout.read().split():
+        for dir_part in os.path.dirname(file).split(os.sep):
+          if self.IgnoreDir(dir_part):
+            break
+        else:
+          if self.IsRelevant(file) and not self.IgnoreFile(file):
+            result.append(join(path, file))
+      if output.wait() == 0:
+        return result
+    return super(SourceProcessor, self).FindFilesIn(path)
+
   def IsRelevant(self, name):
     for ext in SourceProcessor.RELEVANT_EXTENSIONS:
       if name.endswith(ext):
@@ -273,6 +291,22 @@
       if not COPYRIGHT_HEADER_PATTERN.search(contents):
         print "%s is missing a correct copyright header." % name
         result = False
+    ext = base.split('.').pop()
+    if ' \n' in contents or contents.endswith(' '):
+      line = 0
+      lines = []
+      parts = contents.split(' \n')
+      if not contents.endswith(' '):
+        parts.pop()
+      for part in parts:
+        line += part.count('\n') + 1
+        lines.append(str(line))
+      linenumbers = ', '.join(lines)
+      if len(lines) > 1:
+        print "%s has trailing whitespaces in lines %s." % (name, linenumbers)
+      else:
+        print "%s has trailing whitespaces in line %s." % (name, linenumbers)
+      result = False
     return result
 
   def ProcessFiles(self, files, path):
diff --git a/tools/process-heap-prof.py b/tools/process-heap-prof.py
index 6a2c397..a26cbf1 100755
--- a/tools/process-heap-prof.py
+++ b/tools/process-heap-prof.py
@@ -47,7 +47,7 @@
     itemname = 'heap-js-cons-item'
   else:
     itemname = 'heap-sample-item'
-  
+
   first_call_time = None
   sample_time = 0.0
   sampling = False
@@ -108,11 +108,11 @@
   if not ProcessOptions(options):
     parser.print_help()
     sys.exit();
-  
+
   if not args:
     print "Missing logfile"
     sys.exit();
-    
+
   ProcessLogFile(args[0], options)
 
 
diff --git a/tools/test-wrapper-gypbuild.py b/tools/test-wrapper-gypbuild.py
index 9bc6bf6..ad5449a 100755
--- a/tools/test-wrapper-gypbuild.py
+++ b/tools/test-wrapper-gypbuild.py
@@ -53,6 +53,9 @@
   result.add_option("--outdir",
                     help='Base output directory',
                     default='out')
+  result.add_option("--no-presubmit",
+                    help='Skip presubmit checks',
+                    default=False, action="store_true")
 
   # Flags this wrapper script handles itself:
   result.add_option("-m", "--mode",
@@ -202,22 +205,31 @@
     return 1
 
   workspace = abspath(join(dirname(sys.argv[0]), '..'))
+
+  if not options.no_presubmit:
+    print ">>> running presubmit tests"
+    subprocess.call([workspace + '/tools/presubmit.py'])
+
   args_for_children = [workspace + '/tools/test.py'] + PassOnOptions(options)
   args_for_children += ['--no-build', '--build-system=gyp']
   for arg in args:
     args_for_children += [arg]
   returncodes = 0
+  env = os.environ
 
   for mode in options.mode:
     for arch in options.arch:
       print ">>> running tests for %s.%s" % (arch, mode)
-      shell = workspace + '/' + options.outdir + '/' + arch + '.' + mode + "/d8"
+      shellpath = workspace + '/' + options.outdir + '/' + arch + '.' + mode
+      env['LD_LIBRARY_PATH'] = shellpath + '/lib.target'
+      shell = shellpath + "/d8"
       child = subprocess.Popen(' '.join(args_for_children +
                                         ['--arch=' + arch] +
                                         ['--mode=' + mode] +
                                         ['--shell=' + shell]),
                                shell=True,
-                               cwd=workspace)
+                               cwd=workspace,
+                               env=env)
       returncodes += child.wait()
 
   return returncodes
diff --git a/tools/test.py b/tools/test.py
index d40159c..ecc0062 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -1164,6 +1164,7 @@
 
 
 ARCH_GUESS = utils.GuessArchitecture()
+TIMEOUT_DEFAULT = 60;
 
 
 def BuildOptions():
@@ -1188,7 +1189,7 @@
   result.add_option("-s", "--suite", help="A test suite",
       default=[], action="append")
   result.add_option("-t", "--timeout", help="Timeout in seconds",
-      default=60, type="int")
+      default=-1, type="int")
   result.add_option("--arch", help='The architecture to run tests for',
       default='none')
   result.add_option("--snapshot", help="Run the tests with snapshot turned on",
@@ -1262,6 +1263,12 @@
     if options.arch == 'none':
       options.arch = ARCH_GUESS
     options.scons_flags.append("arch=" + options.arch)
+  # Simulators are slow, therefore allow a longer default timeout.
+  if options.timeout == -1:
+    if options.arch == 'arm' or options.arch == 'mips':
+      options.timeout = 2 * TIMEOUT_DEFAULT;
+    else:
+      options.timeout = TIMEOUT_DEFAULT;
   if options.snapshot:
     options.scons_flags.append("snapshot=on")
   global VARIANT_FLAGS