aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2012-01-16 14:37:57 -0800
committerRyan Dahl <ry@tinyclouds.org>2012-01-16 14:37:57 -0800
commit60040a4f366d436d759729530f4d19e7e1958e51 (patch)
tree953a40adf24a0826836cc69843ea80d197a12dab
parent1afd0b52fe9bb4642a44b48dabf9d7b26d00e4ab (diff)
downloadandroid-node-v8-60040a4f366d436d759729530f4d19e7e1958e51.tar.gz
android-node-v8-60040a4f366d436d759729530f4d19e7e1958e51.tar.bz2
android-node-v8-60040a4f366d436d759729530f4d19e7e1958e51.zip
Upgrade V8 to 3.8.6
-rw-r--r--deps/v8/ChangeLog19
-rw-r--r--deps/v8/include/v8.h20
-rw-r--r--deps/v8/src/api.cc34
-rw-r--r--deps/v8/src/arm/assembler-arm-inl.h9
-rw-r--r--deps/v8/src/arm/assembler-arm.cc6
-rw-r--r--deps/v8/src/arm/assembler-arm.h10
-rw-r--r--deps/v8/src/arm/builtins-arm.cc13
-rw-r--r--deps/v8/src/arm/code-stubs-arm.cc44
-rw-r--r--deps/v8/src/arm/cpu-arm.cc2
-rw-r--r--deps/v8/src/arm/deoptimizer-arm.cc7
-rw-r--r--deps/v8/src/arm/full-codegen-arm.cc2
-rw-r--r--deps/v8/src/arm/lithium-arm.cc42
-rw-r--r--deps/v8/src/arm/lithium-arm.h14
-rw-r--r--deps/v8/src/arm/lithium-codegen-arm.cc78
-rw-r--r--deps/v8/src/arm/lithium-codegen-arm.h10
-rw-r--r--deps/v8/src/arm/lithium-gap-resolver-arm.cc21
-rw-r--r--deps/v8/src/arm/macro-assembler-arm.cc119
-rw-r--r--deps/v8/src/arm/macro-assembler-arm.h34
-rw-r--r--deps/v8/src/arm/simulator-arm.cc8
-rw-r--r--deps/v8/src/arm/stub-cache-arm.cc44
-rw-r--r--deps/v8/src/assembler.h2
-rw-r--r--deps/v8/src/atomicops_internals_x86_macosx.h44
-rw-r--r--deps/v8/src/bootstrapper.cc152
-rw-r--r--deps/v8/src/bootstrapper.h2
-rw-r--r--deps/v8/src/builtins.cc2
-rw-r--r--deps/v8/src/builtins.h2
-rw-r--r--deps/v8/src/code-stubs.cc6
-rw-r--r--deps/v8/src/compiler.cc2
-rw-r--r--deps/v8/src/cpu-profiler.cc4
-rw-r--r--deps/v8/src/cpu-profiler.h6
-rw-r--r--deps/v8/src/cpu.h2
-rw-r--r--deps/v8/src/d8-debug.cc2
-rw-r--r--deps/v8/src/d8.cc189
-rw-r--r--deps/v8/src/d8.h3
-rw-r--r--deps/v8/src/debug-debugger.js2
-rw-r--r--deps/v8/src/debug.cc12
-rw-r--r--deps/v8/src/debug.h6
-rw-r--r--deps/v8/src/elements.cc19
-rw-r--r--deps/v8/src/execution.cc4
-rw-r--r--deps/v8/src/execution.h2
-rw-r--r--deps/v8/src/factory.cc48
-rw-r--r--deps/v8/src/factory.h17
-rw-r--r--deps/v8/src/flag-definitions.h8
-rw-r--r--deps/v8/src/frames.cc5
-rw-r--r--deps/v8/src/full-codegen.cc4
-rw-r--r--deps/v8/src/gdb-jit.cc44
-rw-r--r--deps/v8/src/handles.cc162
-rw-r--r--deps/v8/src/handles.h65
-rw-r--r--deps/v8/src/heap-inl.h2
-rw-r--r--deps/v8/src/heap-profiler.cc2
-rw-r--r--deps/v8/src/heap-profiler.h2
-rw-r--r--deps/v8/src/heap.cc103
-rw-r--r--deps/v8/src/heap.h31
-rw-r--r--deps/v8/src/hydrogen-instructions.cc25
-rw-r--r--deps/v8/src/hydrogen-instructions.h45
-rw-r--r--deps/v8/src/hydrogen.cc99
-rw-r--r--deps/v8/src/hydrogen.h2
-rw-r--r--deps/v8/src/ia32/assembler-ia32.cc6
-rw-r--r--deps/v8/src/ia32/builtins-ia32.cc2
-rw-r--r--deps/v8/src/ia32/code-stubs-ia32.cc37
-rw-r--r--deps/v8/src/ia32/cpu-ia32.cc2
-rw-r--r--deps/v8/src/ia32/deoptimizer-ia32.cc2
-rw-r--r--deps/v8/src/ia32/full-codegen-ia32.cc2
-rw-r--r--deps/v8/src/ia32/lithium-codegen-ia32.cc94
-rw-r--r--deps/v8/src/ia32/lithium-codegen-ia32.h9
-rw-r--r--deps/v8/src/ia32/lithium-ia32.cc55
-rw-r--r--deps/v8/src/ia32/lithium-ia32.h19
-rw-r--r--deps/v8/src/ia32/macro-assembler-ia32.cc124
-rw-r--r--deps/v8/src/ia32/macro-assembler-ia32.h20
-rw-r--r--deps/v8/src/ia32/stub-cache-ia32.cc42
-rw-r--r--deps/v8/src/ic.cc6
-rw-r--r--deps/v8/src/incremental-marking.cc2
-rw-r--r--deps/v8/src/incremental-marking.h5
-rw-r--r--deps/v8/src/inspector.cc4
-rw-r--r--deps/v8/src/inspector.h8
-rw-r--r--deps/v8/src/isolate.cc59
-rw-r--r--deps/v8/src/isolate.h7
-rw-r--r--deps/v8/src/json-parser.h5
-rw-r--r--deps/v8/src/jsregexp.cc2
-rw-r--r--deps/v8/src/lithium-allocator.cc4
-rw-r--r--deps/v8/src/lithium.h14
-rw-r--r--deps/v8/src/liveedit.cc4
-rw-r--r--deps/v8/src/liveobjectlist-inl.h4
-rw-r--r--deps/v8/src/liveobjectlist.cc48
-rw-r--r--deps/v8/src/liveobjectlist.h10
-rw-r--r--deps/v8/src/log.cc6
-rw-r--r--deps/v8/src/log.h6
-rw-r--r--deps/v8/src/mark-compact.cc1
-rw-r--r--deps/v8/src/mips/assembler-mips-inl.h2
-rw-r--r--deps/v8/src/mips/assembler-mips.cc6
-rw-r--r--deps/v8/src/mips/builtins-mips.cc13
-rw-r--r--deps/v8/src/mips/code-stubs-mips.cc37
-rw-r--r--deps/v8/src/mips/constants-mips.h4
-rw-r--r--deps/v8/src/mips/cpu-mips.cc2
-rw-r--r--deps/v8/src/mips/deoptimizer-mips.cc7
-rw-r--r--deps/v8/src/mips/full-codegen-mips.cc2
-rw-r--r--deps/v8/src/mips/lithium-codegen-mips.cc25
-rw-r--r--deps/v8/src/mips/lithium-codegen-mips.h8
-rw-r--r--deps/v8/src/mips/lithium-gap-resolver-mips.cc4
-rw-r--r--deps/v8/src/mips/lithium-mips.cc40
-rw-r--r--deps/v8/src/mips/lithium-mips.h14
-rw-r--r--deps/v8/src/mips/macro-assembler-mips.cc92
-rw-r--r--deps/v8/src/mips/macro-assembler-mips.h18
-rw-r--r--deps/v8/src/mips/simulator-mips.cc10
-rw-r--r--deps/v8/src/mips/stub-cache-mips.cc4
-rw-r--r--deps/v8/src/objects-debug.cc9
-rw-r--r--deps/v8/src/objects-inl.h38
-rw-r--r--deps/v8/src/objects-printer.cc9
-rw-r--r--deps/v8/src/objects.cc502
-rw-r--r--deps/v8/src/objects.h232
-rw-r--r--deps/v8/src/parser.cc22
-rw-r--r--deps/v8/src/platform-cygwin.cc4
-rw-r--r--deps/v8/src/platform-freebsd.cc2
-rw-r--r--deps/v8/src/platform-linux.cc4
-rw-r--r--deps/v8/src/platform-macos.cc2
-rw-r--r--deps/v8/src/platform-nullos.cc2
-rw-r--r--deps/v8/src/platform-openbsd.cc4
-rw-r--r--deps/v8/src/platform-posix.cc2
-rw-r--r--deps/v8/src/platform-solaris.cc2
-rw-r--r--deps/v8/src/platform-win32.cc4
-rw-r--r--deps/v8/src/platform.h8
-rw-r--r--deps/v8/src/preparser.h2
-rw-r--r--deps/v8/src/profile-generator.cc54
-rw-r--r--deps/v8/src/profile-generator.h14
-rw-r--r--deps/v8/src/runtime-profiler.cc10
-rw-r--r--deps/v8/src/runtime-profiler.h6
-rw-r--r--deps/v8/src/runtime.cc253
-rw-r--r--deps/v8/src/scopes.cc2
-rw-r--r--deps/v8/src/spaces.cc29
-rw-r--r--deps/v8/src/spaces.h45
-rw-r--r--deps/v8/src/store-buffer.cc2
-rw-r--r--deps/v8/src/store-buffer.h2
-rw-r--r--deps/v8/src/stub-cache.cc35
-rw-r--r--deps/v8/src/type-info.cc6
-rw-r--r--deps/v8/src/type-info.h2
-rw-r--r--deps/v8/src/utils.h8
-rw-r--r--deps/v8/src/v8.cc12
-rw-r--r--deps/v8/src/v8.h2
-rw-r--r--deps/v8/src/v8globals.h3
-rw-r--r--deps/v8/src/version.cc2
-rw-r--r--deps/v8/src/win32-headers.h2
-rw-r--r--deps/v8/src/x64/assembler-x64-inl.h2
-rw-r--r--deps/v8/src/x64/assembler-x64.cc6
-rw-r--r--deps/v8/src/x64/builtins-x64.cc4
-rw-r--r--deps/v8/src/x64/code-stubs-x64.cc29
-rw-r--r--deps/v8/src/x64/cpu-x64.cc2
-rw-r--r--deps/v8/src/x64/deoptimizer-x64.cc2
-rw-r--r--deps/v8/src/x64/full-codegen-x64.cc2
-rw-r--r--deps/v8/src/x64/lithium-codegen-x64.cc98
-rw-r--r--deps/v8/src/x64/lithium-codegen-x64.h10
-rw-r--r--deps/v8/src/x64/lithium-x64.cc49
-rw-r--r--deps/v8/src/x64/lithium-x64.h14
-rw-r--r--deps/v8/src/x64/macro-assembler-x64.cc120
-rw-r--r--deps/v8/src/x64/macro-assembler-x64.h24
-rw-r--r--deps/v8/src/x64/stub-cache-x64.cc40
-rw-r--r--deps/v8/test/cctest/SConscript1
-rw-r--r--deps/v8/test/cctest/cctest.h2
-rw-r--r--deps/v8/test/cctest/test-alloc.cc4
-rw-r--r--deps/v8/test/cctest/test-api.cc118
-rw-r--r--deps/v8/test/cctest/test-assembler-x64.cc14
-rw-r--r--deps/v8/test/cctest/test-cpu-profiler.cc4
-rw-r--r--deps/v8/test/cctest/test-debug.cc16
-rw-r--r--deps/v8/test/cctest/test-disasm-arm.cc14
-rw-r--r--deps/v8/test/cctest/test-disasm-mips.cc6
-rw-r--r--deps/v8/test/cctest/test-hashing.cc153
-rw-r--r--deps/v8/test/cctest/test-heap.cc96
-rw-r--r--deps/v8/test/cctest/test-platform-linux.cc2
-rw-r--r--deps/v8/test/cctest/test-platform-win32.cc2
-rw-r--r--deps/v8/test/cctest/test-sockets.cc2
-rw-r--r--deps/v8/test/cctest/test-spaces.cc18
-rw-r--r--deps/v8/test/cctest/test-utils.cc2
-rw-r--r--deps/v8/test/mjsunit/external-array.js46
-rw-r--r--deps/v8/test/mjsunit/math-min-max.js64
-rw-r--r--deps/v8/test/mjsunit/regress/regress-109195.js65
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1898.js37
-rwxr-xr-xdeps/v8/tools/grokdump.py59
-rwxr-xr-xdeps/v8/tools/ll_prof.py8
177 files changed, 3329 insertions, 1703 deletions
diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog
index 059b69252e..1c1bddda82 100644
--- a/deps/v8/ChangeLog
+++ b/deps/v8/ChangeLog
@@ -1,3 +1,22 @@
+2012-01-16: Version 3.8.6
+
+ Add primitive WebGL array support to d8.
+
+ Improve heap size estimation (issue 1893).
+
+ Hash collision DOS workaround extended from string keys
+ to numeric keys.
+
+ Provide an API for iterating through all external strings referenced
+ from the JS heap.
+
+ Adjust position recorded for call expressions. http://crbug.com/109195
+
+ Fix GC crash related to instanceof. http://crbug.com/109448
+
+ Performance improvements and bug fixes.
+
+
2012-01-05: Version 3.8.5
Fix broken test that assumes that no GC can clear the regexp cache (GC
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h
index 1819943580..294b14d386 100644
--- a/deps/v8/include/v8.h
+++ b/deps/v8/include/v8.h
@@ -2848,6 +2848,17 @@ class V8EXPORT StartupDataDecompressor { // NOLINT
*/
typedef bool (*EntropySource)(unsigned char* buffer, size_t length);
+
+/**
+ * Interface for iterating though all external resources in the heap.
+ */
+class V8EXPORT ExternalResourceVisitor { // NOLINT
+ public:
+ virtual ~ExternalResourceVisitor() {}
+ virtual void VisitExternalString(Handle<String> string) {}
+};
+
+
/**
* Container class for static utility functions.
*/
@@ -3204,6 +3215,13 @@ class V8EXPORT V8 {
static void GetHeapStatistics(HeapStatistics* heap_statistics);
/**
+ * Iterates through all external resources referenced from current isolate
+ * heap. This method is not expected to be used except for debugging purposes
+ * and may be quite slow.
+ */
+ static void VisitExternalResources(ExternalResourceVisitor* visitor);
+
+ /**
* Optional notification that the embedder is idle.
* V8 uses the notification to reduce memory footprint.
* This call can be used repeatedly if the embedder remains idle.
@@ -3816,7 +3834,7 @@ class Internals {
static const int kFullStringRepresentationMask = 0x07;
static const int kExternalTwoByteRepresentationTag = 0x02;
- static const int kJSObjectType = 0xa6;
+ static const int kJSObjectType = 0xa7;
static const int kFirstNonstringType = 0x80;
static const int kForeignType = 0x85;
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 3bd5a3180f..bac3069308 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -2165,6 +2165,11 @@ bool Value::IsInt32() const {
if (obj->IsSmi()) return true;
if (obj->IsNumber()) {
double value = obj->Number();
+ static const i::DoubleRepresentation minus_zero(-0.0);
+ i::DoubleRepresentation rep(value);
+ if (rep.bits == minus_zero.bits) {
+ return false;
+ }
return i::FastI2D(i::FastD2I(value)) == value;
}
return false;
@@ -2177,6 +2182,11 @@ bool Value::IsUint32() const {
if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
if (obj->IsNumber()) {
double value = obj->Number();
+ static const i::DoubleRepresentation minus_zero(-0.0);
+ i::DoubleRepresentation rep(value);
+ if (rep.bits == minus_zero.bits) {
+ return false;
+ }
return i::FastUI2D(i::FastD2UI(value)) == value;
}
return false;
@@ -2739,7 +2749,7 @@ bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj = i::SetElement(
+ i::Handle<i::Object> obj = i::JSObject::SetElement(
self,
index,
value_obj,
@@ -2845,7 +2855,7 @@ Local<Value> v8::Object::GetPrototype() {
return Local<v8::Value>());
ENTER_V8(isolate);
i::Handle<i::Object> self = Utils::OpenHandle(this);
- i::Handle<i::Object> result = i::GetPrototype(self);
+ i::Handle<i::Object> result(self->GetPrototype());
return Utils::ToLocal(result);
}
@@ -2999,7 +3009,7 @@ bool v8::Object::Delete(v8::Handle<String> key) {
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
- return i::DeleteProperty(self, key_obj)->IsTrue();
+ return i::JSObject::DeleteProperty(self, key_obj)->IsTrue();
}
@@ -3020,7 +3030,7 @@ bool v8::Object::Delete(uint32_t index) {
ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- return i::DeleteElement(self, index)->IsTrue();
+ return i::JSObject::DeleteElement(self, index)->IsTrue();
}
@@ -3225,7 +3235,7 @@ int v8::Object::GetIdentityHash() {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- return i::GetIdentityHash(self);
+ return i::JSObject::GetIdentityHash(self);
}
@@ -3238,7 +3248,8 @@ bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- i::Handle<i::Object> result = i::SetHiddenProperty(self, key_obj, value_obj);
+ i::Handle<i::Object> result =
+ i::JSObject::SetHiddenProperty(self, key_obj, value_obj);
return *result == *self;
}
@@ -4038,6 +4049,13 @@ void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
}
+void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
+ i::Isolate* isolate = i::Isolate::Current();
+ IsDeadCheck(isolate, "v8::V8::VisitExternalResources");
+ isolate->heap()->VisitExternalResources(visitor);
+}
+
+
bool v8::V8::IdleNotification(int hint) {
// Returning true tells the caller that it need not
// continue to call IdleNotification.
@@ -5542,7 +5560,7 @@ void Debug::DisableAgent() {
void Debug::ProcessDebugMessages() {
- i::Execution::ProcessDebugMesssages(true);
+ i::Execution::ProcessDebugMessages(true);
}
Local<Context> Debug::GetDebugContext() {
diff --git a/deps/v8/src/arm/assembler-arm-inl.h b/deps/v8/src/arm/assembler-arm-inl.h
index 79f9c7bd2b..2ec6c7cfa7 100644
--- a/deps/v8/src/arm/assembler-arm-inl.h
+++ b/deps/v8/src/arm/assembler-arm-inl.h
@@ -32,7 +32,7 @@
// The original source code covered by the above license above has been modified
// significantly by Google Inc.
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
#ifndef V8_ARM_ASSEMBLER_ARM_INL_H_
#define V8_ARM_ASSEMBLER_ARM_INL_H_
@@ -46,6 +46,13 @@ namespace v8 {
namespace internal {
+int DwVfpRegister::ToAllocationIndex(DwVfpRegister reg) {
+ ASSERT(!reg.is(kDoubleRegZero));
+ ASSERT(!reg.is(kScratchDoubleReg));
+ return reg.code();
+}
+
+
void RelocInfo::apply(intptr_t delta) {
if (RelocInfo::IsInternalReference(rmode_)) {
// absolute code pointer inside code object moves with the code object.
diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc
index 329493a340..25922361a2 100644
--- a/deps/v8/src/arm/assembler-arm.cc
+++ b/deps/v8/src/arm/assembler-arm.cc
@@ -317,7 +317,7 @@ Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
own_buffer_ = false;
}
- // Setup buffer pointers.
+ // Set up buffer pointers.
ASSERT(buffer_ != NULL);
pc_ = buffer_;
reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
@@ -349,7 +349,7 @@ void Assembler::GetCode(CodeDesc* desc) {
CheckConstPool(true, false);
ASSERT(num_pending_reloc_info_ == 0);
- // Setup code descriptor.
+ // Set up code descriptor.
desc->buffer = buffer_;
desc->buffer_size = buffer_size_;
desc->instr_size = pc_offset();
@@ -2446,7 +2446,7 @@ void Assembler::GrowBuffer() {
}
CHECK_GT(desc.buffer_size, 0); // no overflow
- // Setup new buffer.
+ // Set up new buffer.
desc.buffer = NewArray<byte>(desc.buffer_size);
desc.instr_size = pc_offset();
diff --git a/deps/v8/src/arm/assembler-arm.h b/deps/v8/src/arm/assembler-arm.h
index 247479d730..e88739e497 100644
--- a/deps/v8/src/arm/assembler-arm.h
+++ b/deps/v8/src/arm/assembler-arm.h
@@ -32,7 +32,7 @@
// The original source code covered by the above license above has been
// modified significantly by Google Inc.
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// A light-weight ARM Assembler
// Generates user mode instructions for the ARM architecture up to version 5
@@ -176,14 +176,11 @@ struct DwVfpRegister {
static const int kNumAllocatableRegisters = kNumRegisters -
kNumReservedRegisters;
- static int ToAllocationIndex(DwVfpRegister reg) {
- ASSERT(reg.code() != 0);
- return reg.code() - 1;
- }
+ inline static int ToAllocationIndex(DwVfpRegister reg);
static DwVfpRegister FromAllocationIndex(int index) {
ASSERT(index >= 0 && index < kNumAllocatableRegisters);
- return from_code(index + 1);
+ return from_code(index);
}
static const char* AllocationIndexToString(int index) {
@@ -307,6 +304,7 @@ const DwVfpRegister d15 = { 15 };
static const DwVfpRegister& kFirstCalleeSavedDoubleReg = d8;
static const DwVfpRegister& kLastCalleeSavedDoubleReg = d15;
static const DwVfpRegister& kDoubleRegZero = d14;
+static const DwVfpRegister& kScratchDoubleReg = d15;
// Coprocessor register
diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc
index 69ef1872c7..2a650a44a5 100644
--- a/deps/v8/src/arm/builtins-arm.cc
+++ b/deps/v8/src/arm/builtins-arm.cc
@@ -333,7 +333,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
r5,
call_generic_code);
__ IncrementCounter(counters->array_function_native(), 1, r3, r4);
- // Setup return value, remove receiver from stack and return.
+ // Set up return value, remove receiver from stack and return.
__ mov(r0, r2);
__ add(sp, sp, Operand(kPointerSize));
__ Jump(lr);
@@ -376,7 +376,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
true,
call_generic_code);
__ IncrementCounter(counters->array_function_native(), 1, r2, r4);
- // Setup return value, remove receiver and argument from stack and return.
+ // Set up return value, remove receiver and argument from stack and return.
__ mov(r0, r3);
__ add(sp, sp, Operand(2 * kPointerSize));
__ Jump(lr);
@@ -951,10 +951,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
// sp[4]: number of arguments (smi-tagged)
__ ldr(r3, MemOperand(sp, 4 * kPointerSize));
- // Setup pointer to last argument.
+ // Set up pointer to last argument.
__ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
- // Setup number of arguments for function call below
+ // Set up number of arguments for function call below
__ mov(r0, Operand(r3, LSR, kSmiTagSize));
// Copy arguments and receiver to the expression stack.
@@ -1082,10 +1082,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// Set up the context from the function argument.
__ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
- // Set up the roots register.
- ExternalReference roots_array_start =
- ExternalReference::roots_array_start(masm->isolate());
- __ mov(r10, Operand(roots_array_start));
+ __ InitializeRootRegister();
// Push the function and the receiver onto the stack.
__ push(r1);
diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc
index e95e2cf421..15ef9bcf9d 100644
--- a/deps/v8/src/arm/code-stubs-arm.cc
+++ b/deps/v8/src/arm/code-stubs-arm.cc
@@ -156,13 +156,13 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
// Load the function from the stack.
__ ldr(r3, MemOperand(sp, 0));
- // Setup the object header.
+ // Set up the object header.
__ LoadRoot(r2, Heap::kFunctionContextMapRootIndex);
__ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
__ mov(r2, Operand(Smi::FromInt(length)));
__ str(r2, FieldMemOperand(r0, FixedArray::kLengthOffset));
- // Setup the fixed slots.
+ // Set up the fixed slots.
__ mov(r1, Operand(Smi::FromInt(0)));
__ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX)));
__ str(cp, MemOperand(r0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
@@ -207,7 +207,7 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
// Load the serialized scope info from the stack.
__ ldr(r1, MemOperand(sp, 1 * kPointerSize));
- // Setup the object header.
+ // Set up the object header.
__ LoadRoot(r2, Heap::kBlockContextMapRootIndex);
__ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
__ mov(r2, Operand(Smi::FromInt(length)));
@@ -229,7 +229,7 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ ldr(r3, ContextOperand(r3, Context::CLOSURE_INDEX));
__ bind(&after_sentinel);
- // Setup the fixed slots.
+ // Set up the fixed slots.
__ str(r3, ContextOperand(r0, Context::CLOSURE_INDEX));
__ str(cp, ContextOperand(r0, Context::PREVIOUS_INDEX));
__ str(r1, ContextOperand(r0, Context::EXTENSION_INDEX));
@@ -717,7 +717,7 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
// Get the absolute value of the object (as an unsigned integer).
__ rsb(int_scratch, int_scratch, Operand::Zero(), SetCC, mi);
- // Get mantisssa[51:20].
+ // Get mantissa[51:20].
// Get the position of the first set bit.
__ CountLeadingZeros(dst1, int_scratch, scratch2);
@@ -951,7 +951,7 @@ void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm,
// non zero bits left. So we need the (30 - exponent) last bits of the
// 31 higher bits of the mantissa to be null.
// Because bits [21:0] are null, we can check instead that the
- // (32 - exponent) last bits of the 32 higher bits of the mantisssa are null.
+ // (32 - exponent) last bits of the 32 higher bits of the mantissa are null.
// Get the 32 higher bits of the mantissa in dst.
__ Ubfx(dst,
@@ -3842,7 +3842,7 @@ void CEntryStub::Generate(MacroAssembler* masm) {
FrameScope scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(save_doubles_);
- // Setup argc and the builtin function in callee-saved registers.
+ // Set up argc and the builtin function in callee-saved registers.
__ mov(r4, Operand(r0));
__ mov(r5, Operand(r1));
@@ -3919,7 +3919,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// r2: receiver
// r3: argc
- // Setup argv in r4.
+ // Set up argv in r4.
int offset_to_argv = (kNumCalleeSaved + 1) * kPointerSize;
if (CpuFeatures::IsSupported(VFP3)) {
offset_to_argv += kNumDoubleCalleeSaved * kDoubleSize;
@@ -3942,7 +3942,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ ldr(r5, MemOperand(r5));
__ Push(r8, r7, r6, r5);
- // Setup frame pointer for the frame to be pushed.
+ // Set up frame pointer for the frame to be pushed.
__ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
// If this is the outermost JS call, set js_entry_sp value.
@@ -4081,7 +4081,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
const Register inline_site = r9;
const Register scratch = r2;
- const int32_t kDeltaToLoadBoolResult = 3 * kPointerSize;
+ const int32_t kDeltaToLoadBoolResult = 4 * kPointerSize;
Label slow, loop, is_instance, is_not_instance, not_js_object;
@@ -4132,7 +4132,8 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ sub(inline_site, lr, scratch);
// Get the map location in scratch and patch it.
__ GetRelocatedValueLocation(inline_site, scratch);
- __ str(map, MemOperand(scratch));
+ __ ldr(scratch, MemOperand(scratch));
+ __ str(map, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
}
// Register mapping: r3 is object map and r4 is function prototype.
@@ -4401,7 +4402,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
__ str(r3, FieldMemOperand(r0, i));
}
- // Setup the callee in-object property.
+ // Set up the callee in-object property.
STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
__ ldr(r3, MemOperand(sp, 2 * kPointerSize));
const int kCalleeOffset = JSObject::kHeaderSize +
@@ -4414,7 +4415,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
Heap::kArgumentsLengthIndex * kPointerSize;
__ str(r2, FieldMemOperand(r0, kLengthOffset));
- // Setup the elements pointer in the allocated arguments object.
+ // Set up the elements pointer in the allocated arguments object.
// If we allocated a parameter map, r4 will point there, otherwise
// it will point to the backing store.
__ add(r4, r0, Operand(Heap::kArgumentsObjectSize));
@@ -4509,7 +4510,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
__ Ret();
// Do the runtime call to allocate the arguments object.
- // r2 = argument count (taggged)
+ // r2 = argument count (tagged)
__ bind(&runtime);
__ str(r2, MemOperand(sp, 0 * kPointerSize)); // Patch argument count.
__ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
@@ -4582,7 +4583,7 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Get the parameters pointer from the stack.
__ ldr(r2, MemOperand(sp, 1 * kPointerSize));
- // Setup the elements pointer in the allocated arguments object and
+ // Set up the elements pointer in the allocated arguments object and
// initialize the header in the elements fixed array.
__ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict));
__ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
@@ -4594,7 +4595,7 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Copy the fixed array slots.
Label loop;
- // Setup r4 to point to the first array slot.
+ // Set up r4 to point to the first array slot.
__ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ bind(&loop);
// Pre-decrement r2 with kPointerSize on each iteration.
@@ -5209,7 +5210,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// of the original receiver from the call site).
__ bind(&non_function);
__ str(r1, MemOperand(sp, argc_ * kPointerSize));
- __ mov(r0, Operand(argc_)); // Setup the number of arguments.
+ __ mov(r0, Operand(argc_)); // Set up the number of arguments.
__ mov(r2, Operand(0, RelocInfo::NONE));
__ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
__ SetCallKind(r5, CALL_AS_METHOD);
@@ -5730,7 +5731,7 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
Register hash,
Register character) {
// hash = character + (character << 10);
- __ LoadRoot(hash, Heap::kStringHashSeedRootIndex);
+ __ LoadRoot(hash, Heap::kHashSeedRootIndex);
// Untag smi seed and add the character.
__ add(hash, character, Operand(hash, LSR, kSmiTagSize));
// hash += hash << 10;
@@ -5759,13 +5760,12 @@ void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
// hash ^= hash >> 11;
__ eor(hash, hash, Operand(hash, LSR, 11));
// hash += hash << 15;
- __ add(hash, hash, Operand(hash, LSL, 15), SetCC);
+ __ add(hash, hash, Operand(hash, LSL, 15));
- uint32_t kHashShiftCutOffMask = (1 << (32 - String::kHashShift)) - 1;
- __ and_(hash, hash, Operand(kHashShiftCutOffMask));
+ __ and_(hash, hash, Operand(String::kHashBitMask), SetCC);
// if (hash == 0) hash = 27;
- __ mov(hash, Operand(27), LeaveCC, eq);
+ __ mov(hash, Operand(StringHasher::kZeroHash), LeaveCC, eq);
}
diff --git a/deps/v8/src/arm/cpu-arm.cc b/deps/v8/src/arm/cpu-arm.cc
index 51cfeb6c87..7b08ed8c2f 100644
--- a/deps/v8/src/arm/cpu-arm.cc
+++ b/deps/v8/src/arm/cpu-arm.cc
@@ -41,7 +41,7 @@
namespace v8 {
namespace internal {
-void CPU::Setup() {
+void CPU::SetUp() {
CpuFeatures::Probe();
}
diff --git a/deps/v8/src/arm/deoptimizer-arm.cc b/deps/v8/src/arm/deoptimizer-arm.cc
index 4b54b6dbc2..3689a9f6b6 100644
--- a/deps/v8/src/arm/deoptimizer-arm.cc
+++ b/deps/v8/src/arm/deoptimizer-arm.cc
@@ -319,7 +319,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
output_[0] = input_;
output_[0]->SetPc(reinterpret_cast<uint32_t>(from_));
} else {
- // Setup the frame pointer and the context pointer.
+ // Set up the frame pointer and the context pointer.
output_[0]->SetRegister(fp.code(), input_->GetRegister(fp.code()));
output_[0]->SetRegister(cp.code(), input_->GetRegister(cp.code()));
@@ -723,10 +723,7 @@ void Deoptimizer::EntryGenerator::Generate() {
__ pop(ip); // remove sp
__ pop(ip); // remove lr
- // Set up the roots register.
- ExternalReference roots_array_start =
- ExternalReference::roots_array_start(isolate);
- __ mov(r10, Operand(roots_array_start));
+ __ InitializeRootRegister();
__ pop(ip); // remove pc
__ pop(r7); // get continuation, leave pc on stack
diff --git a/deps/v8/src/arm/full-codegen-arm.cc b/deps/v8/src/arm/full-codegen-arm.cc
index 7e9a889116..38999a8e36 100644
--- a/deps/v8/src/arm/full-codegen-arm.cc
+++ b/deps/v8/src/arm/full-codegen-arm.cc
@@ -1009,7 +1009,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ ldr(r1, FieldMemOperand(r1, DescriptorArray::kEnumerationIndexOffset));
__ ldr(r2, FieldMemOperand(r1, DescriptorArray::kEnumCacheBridgeCacheOffset));
- // Setup the four remaining stack slots.
+ // Set up the four remaining stack slots.
__ push(r0); // Map.
__ ldr(r1, FieldMemOperand(r2, FixedArray::kLengthOffset));
__ mov(r0, Operand(Smi::FromInt(0)));
diff --git a/deps/v8/src/arm/lithium-arm.cc b/deps/v8/src/arm/lithium-arm.cc
index b001ecada0..e063ef1132 100644
--- a/deps/v8/src/arm/lithium-arm.cc
+++ b/deps/v8/src/arm/lithium-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -1038,14 +1038,23 @@ LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
- HValue* v = instr->value();
- if (v->EmitAtUses()) {
- HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
+ HValue* value = instr->value();
+ if (value->EmitAtUses()) {
+ HBasicBlock* successor = HConstant::cast(value)->ToBoolean()
? instr->FirstSuccessor()
: instr->SecondSuccessor();
return new LGoto(successor->block_id());
}
- return AssignEnvironment(new LBranch(UseRegister(v)));
+
+ LBranch* result = new LBranch(UseRegister(value));
+ // Tagged values that are not known smis or booleans require a
+ // deoptimization environment.
+ Representation rep = value->representation();
+ HType type = value->type();
+ if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean()) {
+ return AssignEnvironment(result);
+ }
+ return result;
}
@@ -1344,7 +1353,12 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
} else {
left = UseRegisterAtStart(instr->LeastConstantOperand());
}
- return AssignEnvironment(DefineAsRegister(new LMulI(left, right, temp)));
+ LMulI* mul = new LMulI(left, right, temp);
+ if (instr->CheckFlag(HValue::kCanOverflow) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ AssignEnvironment(mul);
+ }
+ return DefineAsRegister(mul);
} else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::MUL, instr);
@@ -1413,6 +1427,15 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
}
+LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->global_object()->representation().IsTagged());
+ LOperand* global_object = UseFixed(instr->global_object(), r0);
+ LRandom* result = new LRandom(global_object);
+ return MarkAsCall(DefineFixedDouble(result, d7), instr);
+}
+
+
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
ASSERT(instr->left()->representation().IsTagged());
ASSERT(instr->right()->representation().IsTagged());
@@ -1529,7 +1552,7 @@ LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
HClassOfTestAndBranch* instr) {
ASSERT(instr->value()->representation().IsTagged());
- return new LClassOfTestAndBranch(UseTempRegister(instr->value()),
+ return new LClassOfTestAndBranch(UseRegister(instr->value()),
TempRegister());
}
@@ -1556,7 +1579,7 @@ LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
LOperand* object = UseRegister(instr->value());
LValueOf* result = new LValueOf(object, TempRegister());
- return AssignEnvironment(DefineAsRegister(result));
+ return DefineAsRegister(result);
}
@@ -1874,7 +1897,8 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterAtStart(instr->key());
LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
- return AssignEnvironment(DefineAsRegister(result));
+ if (instr->RequiresHoleCheck()) AssignEnvironment(result);
+ return DefineAsRegister(result);
}
diff --git a/deps/v8/src/arm/lithium-arm.h b/deps/v8/src/arm/lithium-arm.h
index 703666c4a1..d3aff76e18 100644
--- a/deps/v8/src/arm/lithium-arm.h
+++ b/deps/v8/src/arm/lithium-arm.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -141,6 +141,7 @@ class LCodeGen;
V(Parameter) \
V(Power) \
V(PushArgument) \
+ V(Random) \
V(RegExpLiteral) \
V(Return) \
V(ShiftI) \
@@ -1026,6 +1027,17 @@ class LPower: public LTemplateInstruction<1, 2, 0> {
};
+class LRandom: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LRandom(LOperand* global_object) {
+ inputs_[0] = global_object;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Random, "random")
+ DECLARE_HYDROGEN_ACCESSOR(Random)
+};
+
+
class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
public:
LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc
index e1e35d251e..b5ed517087 100644
--- a/deps/v8/src/arm/lithium-codegen-arm.cc
+++ b/deps/v8/src/arm/lithium-codegen-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -1994,7 +1994,7 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
// Branches to a label or falls through with the answer in flags. Trashes
-// the temp registers, but not the input. Only input and temp2 may alias.
+// the temp registers, but not the input.
void LCodeGen::EmitClassOfTest(Label* is_true,
Label* is_false,
Handle<String>class_name,
@@ -2002,7 +2002,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
Register temp,
Register temp2) {
ASSERT(!input.is(temp));
- ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register.
+ ASSERT(!input.is(temp2));
+ ASSERT(!temp.is(temp2));
+
__ JumpIfSmi(input, is_false);
if (class_name->IsEqualTo(CStrVector("Function"))) {
@@ -2141,7 +2143,10 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
// We use Factory::the_hole_value() on purpose instead of loading from the
// root array to force relocation to be able to later patch with
// the cached map.
- __ mov(ip, Operand(factory()->the_hole_value()));
+ Handle<JSGlobalPropertyCell> cell =
+ factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
+ __ mov(ip, Operand(Handle<Object>(cell)));
+ __ ldr(ip, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
__ cmp(map, Operand(ip));
__ b(ne, &cache_miss);
// We use Factory::the_hole_value() on purpose instead of loading from the
@@ -2901,7 +2906,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
__ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
__ Call(ip);
- // Setup deoptimization.
+ // Set up deoptimization.
RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
// Restore context.
@@ -3190,6 +3195,30 @@ void LCodeGen::DoPower(LPower* instr) {
}
+void LCodeGen::DoRandom(LRandom* instr) {
+ // Having marked this instruction as a call we can use any
+ // registers.
+ ASSERT(ToDoubleRegister(instr->result()).is(d7));
+ ASSERT(ToRegister(instr->InputAt(0)).is(r0));
+
+ __ PrepareCallCFunction(1, scratch0());
+ __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset));
+ __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
+
+ // 0x41300000 is the top half of 1.0 x 2^20 as a double.
+ // Create this constant using mov/orr to avoid PC relative load.
+ __ mov(r1, Operand(0x41000000));
+ __ orr(r1, r1, Operand(0x300000));
+ // Move 0x41300000xxxxxxxx (x = random bits) to VFP.
+ __ vmov(d7, r0, r1);
+ // Move 0x4130000000000000 to VFP.
+ __ mov(r0, Operand(0, RelocInfo::NONE));
+ __ vmov(d8, r0, r1);
+ // Subtract and store the result in the heap number.
+ __ vsub(d7, d7, d8);
+}
+
+
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
ASSERT(ToDoubleRegister(instr->result()).is(d2));
TranscendentalCacheStub stub(TranscendentalCache::LOG,
@@ -3874,6 +3903,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
void LCodeGen::EmitNumberUntagD(Register input_reg,
DoubleRegister result_reg,
bool deoptimize_on_undefined,
+ bool deoptimize_on_minus_zero,
LEnvironment* env) {
Register scratch = scratch0();
SwVfpRegister flt_scratch = double_scratch0().low();
@@ -3909,6 +3939,14 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
// Heap number to double register conversion.
__ sub(ip, input_reg, Operand(kHeapObjectTag));
__ vldr(result_reg, ip, HeapNumber::kValueOffset);
+ if (deoptimize_on_minus_zero) {
+ __ vmov(ip, result_reg.low());
+ __ cmp(ip, Operand(0));
+ __ b(ne, &done);
+ __ vmov(ip, result_reg.high());
+ __ cmp(ip, Operand(HeapNumber::kSignMask));
+ DeoptimizeIf(eq, env);
+ }
__ jmp(&done);
// Smi to double register conversion
@@ -4042,6 +4080,7 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
EmitNumberUntagD(input_reg, result_reg,
instr->hydrogen()->deoptimize_on_undefined(),
+ instr->hydrogen()->deoptimize_on_minus_zero(),
instr->environment());
}
@@ -4155,14 +4194,26 @@ void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
}
+void LCodeGen::DoCheckMapCommon(Register reg,
+ Register scratch,
+ Handle<Map> map,
+ CompareMapMode mode,
+ LEnvironment* env) {
+ Label success;
+ __ CompareMap(reg, scratch, map, &success, mode);
+ DeoptimizeIf(ne, env);
+ __ bind(&success);
+}
+
+
void LCodeGen::DoCheckMap(LCheckMap* instr) {
Register scratch = scratch0();
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
- __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
- __ cmp(scratch, Operand(instr->hydrogen()->map()));
- DeoptimizeIf(ne, instr->environment());
+ Handle<Map> map = instr->hydrogen()->map();
+ DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(),
+ instr->environment());
}
@@ -4231,9 +4282,9 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
// Check prototype maps up to the holder.
while (!current_prototype.is_identical_to(holder)) {
- __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
- __ cmp(temp2, Operand(Handle<Map>(current_prototype->map())));
- DeoptimizeIf(ne, instr->environment());
+ DoCheckMapCommon(temp1, temp2,
+ Handle<Map>(current_prototype->map()),
+ ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
current_prototype =
Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
// Load next prototype object.
@@ -4241,8 +4292,9 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
}
// Check the holder map.
- __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
- __ cmp(temp2, Operand(Handle<Map>(current_prototype->map())));
+ DoCheckMapCommon(temp1, temp2,
+ Handle<Map>(current_prototype->map()),
+ ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
DeoptimizeIf(ne, instr->environment());
}
diff --git a/deps/v8/src/arm/lithium-codegen-arm.h b/deps/v8/src/arm/lithium-codegen-arm.h
index e6626481b3..00823e1638 100644
--- a/deps/v8/src/arm/lithium-codegen-arm.h
+++ b/deps/v8/src/arm/lithium-codegen-arm.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -119,6 +119,9 @@ class LCodeGen BASE_EMBEDDED {
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
Label* map_check);
+ void DoCheckMapCommon(Register reg, Register scratch, Handle<Map> map,
+ CompareMapMode mode, LEnvironment* env);
+
// Parallel move support.
void DoParallelMove(LParallelMove* move);
void DoGap(LGap* instr);
@@ -153,7 +156,7 @@ class LCodeGen BASE_EMBEDDED {
HGraph* graph() const { return chunk_->graph(); }
Register scratch0() { return r9; }
- DwVfpRegister double_scratch0() { return d15; }
+ DwVfpRegister double_scratch0() { return kScratchDoubleReg; }
int GetNextEmittedBlock(int block);
LInstruction* GetNextInstruction();
@@ -270,6 +273,7 @@ class LCodeGen BASE_EMBEDDED {
void EmitNumberUntagD(Register input,
DoubleRegister result,
bool deoptimize_on_undefined,
+ bool deoptimize_on_minus_zero,
LEnvironment* env);
// Emits optimized code for typeof x == "y". Modifies input register.
@@ -408,7 +412,7 @@ class LDeferredCode: public ZoneObject {
virtual void Generate() = 0;
virtual LInstruction* instr() = 0;
- void SetExit(Label *exit) { external_exit_ = exit; }
+ void SetExit(Label* exit) { external_exit_ = exit; }
Label* entry() { return &entry_; }
Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
int instruction_index() const { return instruction_index_; }
diff --git a/deps/v8/src/arm/lithium-gap-resolver-arm.cc b/deps/v8/src/arm/lithium-gap-resolver-arm.cc
index ee6cb8ec91..cefca476ad 100644
--- a/deps/v8/src/arm/lithium-gap-resolver-arm.cc
+++ b/deps/v8/src/arm/lithium-gap-resolver-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -34,7 +34,6 @@ namespace v8 {
namespace internal {
static const Register kSavedValueRegister = { 9 };
-static const DoubleRegister kSavedDoubleValueRegister = { 0 };
LGapResolver::LGapResolver(LCodeGen* owner)
: cgen_(owner), moves_(32), root_index_(0), in_cycle_(false),
@@ -172,9 +171,9 @@ void LGapResolver::BreakCycle(int index) {
} else if (source->IsStackSlot()) {
__ ldr(kSavedValueRegister, cgen_->ToMemOperand(source));
} else if (source->IsDoubleRegister()) {
- __ vmov(kSavedDoubleValueRegister, cgen_->ToDoubleRegister(source));
+ __ vmov(kScratchDoubleReg, cgen_->ToDoubleRegister(source));
} else if (source->IsDoubleStackSlot()) {
- __ vldr(kSavedDoubleValueRegister, cgen_->ToMemOperand(source));
+ __ vldr(kScratchDoubleReg, cgen_->ToMemOperand(source));
} else {
UNREACHABLE();
}
@@ -193,11 +192,9 @@ void LGapResolver::RestoreValue() {
} else if (saved_destination_->IsStackSlot()) {
__ str(kSavedValueRegister, cgen_->ToMemOperand(saved_destination_));
} else if (saved_destination_->IsDoubleRegister()) {
- __ vmov(cgen_->ToDoubleRegister(saved_destination_),
- kSavedDoubleValueRegister);
+ __ vmov(cgen_->ToDoubleRegister(saved_destination_), kScratchDoubleReg);
} else if (saved_destination_->IsDoubleStackSlot()) {
- __ vstr(kSavedDoubleValueRegister,
- cgen_->ToMemOperand(saved_destination_));
+ __ vstr(kScratchDoubleReg, cgen_->ToMemOperand(saved_destination_));
} else {
UNREACHABLE();
}
@@ -235,8 +232,8 @@ void LGapResolver::EmitMove(int index) {
// ip is overwritten while saving the value to the destination.
// Therefore we can't use ip. It is OK if the read from the source
// destroys ip, since that happens before the value is read.
- __ vldr(kSavedDoubleValueRegister.low(), source_operand);
- __ vstr(kSavedDoubleValueRegister.low(), destination_operand);
+ __ vldr(kScratchDoubleReg.low(), source_operand);
+ __ vstr(kScratchDoubleReg.low(), destination_operand);
} else {
__ ldr(ip, source_operand);
__ str(ip, destination_operand);
@@ -297,8 +294,8 @@ void LGapResolver::EmitMove(int index) {
__ ldr(kSavedValueRegister, source_high_operand);
__ str(kSavedValueRegister, destination_high_operand);
} else {
- __ vldr(kSavedDoubleValueRegister, source_operand);
- __ vstr(kSavedDoubleValueRegister, destination_operand);
+ __ vldr(kScratchDoubleReg, source_operand);
+ __ vstr(kScratchDoubleReg, destination_operand);
}
}
} else {
diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc
index 59a5e5ba79..fa97611cf8 100644
--- a/deps/v8/src/arm/macro-assembler-arm.cc
+++ b/deps/v8/src/arm/macro-assembler-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -396,14 +396,14 @@ void MacroAssembler::Usat(Register dst, int satpos, const Operand& src,
void MacroAssembler::LoadRoot(Register destination,
Heap::RootListIndex index,
Condition cond) {
- ldr(destination, MemOperand(roots, index << kPointerSizeLog2), cond);
+ ldr(destination, MemOperand(kRootRegister, index << kPointerSizeLog2), cond);
}
void MacroAssembler::StoreRoot(Register source,
Heap::RootListIndex index,
Condition cond) {
- str(source, MemOperand(roots, index << kPointerSizeLog2), cond);
+ str(source, MemOperand(kRootRegister, index << kPointerSizeLog2), cond);
}
@@ -496,13 +496,10 @@ void MacroAssembler::RecordWrite(Register object,
// registers are cp.
ASSERT(!address.is(cp) && !value.is(cp));
- if (FLAG_debug_code) {
- Label ok;
+ if (emit_debug_code()) {
ldr(ip, MemOperand(address));
cmp(ip, value);
- b(eq, &ok);
- stop("Wrong address or value passed to RecordWrite");
- bind(&ok);
+ Check(eq, "Wrong address or value passed to RecordWrite");
}
Label done;
@@ -551,7 +548,7 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
SaveFPRegsMode fp_mode,
RememberedSetFinalAction and_then) {
Label done;
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
Label ok;
JumpIfNotInNewSpace(object, scratch, &ok);
stop("Remembered set pointer is in new space");
@@ -820,12 +817,12 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
- // Setup the frame structure on the stack.
+ // Set up the frame structure on the stack.
ASSERT_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement);
ASSERT_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset);
ASSERT_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset);
Push(lr, fp);
- mov(fp, Operand(sp)); // Setup new frame pointer.
+ mov(fp, Operand(sp)); // Set up new frame pointer.
// Reserve room for saved entry sp and code object.
sub(sp, sp, Operand(2 * kPointerSize));
if (emit_debug_code()) {
@@ -1414,6 +1411,35 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
}
+void MacroAssembler::GetNumberHash(Register t0, Register scratch) {
+ // First of all we assign the hash seed to scratch.
+ LoadRoot(scratch, Heap::kHashSeedRootIndex);
+ SmiUntag(scratch);
+
+ // Xor original key with a seed.
+ eor(t0, t0, Operand(scratch));
+
+ // Compute the hash code from the untagged key. This must be kept in sync
+ // with ComputeIntegerHash in utils.h.
+ //
+ // hash = ~hash + (hash << 15);
+ mvn(scratch, Operand(t0));
+ add(t0, scratch, Operand(t0, LSL, 15));
+ // hash = hash ^ (hash >> 12);
+ eor(t0, t0, Operand(t0, LSR, 12));
+ // hash = hash + (hash << 2);
+ add(t0, t0, Operand(t0, LSL, 2));
+ // hash = hash ^ (hash >> 4);
+ eor(t0, t0, Operand(t0, LSR, 4));
+ // hash = hash * 2057;
+ mov(scratch, Operand(t0, LSL, 11));
+ add(t0, t0, Operand(t0, LSL, 3));
+ add(t0, t0, scratch);
+ // hash = hash ^ (hash >> 16);
+ eor(t0, t0, Operand(t0, LSR, 16));
+}
+
+
void MacroAssembler::LoadFromNumberDictionary(Label* miss,
Register elements,
Register key,
@@ -1443,26 +1469,10 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
// t2 - used for the index into the dictionary.
Label done;
- // Compute the hash code from the untagged key. This must be kept in sync
- // with ComputeIntegerHash in utils.h.
- //
- // hash = ~hash + (hash << 15);
- mvn(t1, Operand(t0));
- add(t0, t1, Operand(t0, LSL, 15));
- // hash = hash ^ (hash >> 12);
- eor(t0, t0, Operand(t0, LSR, 12));
- // hash = hash + (hash << 2);
- add(t0, t0, Operand(t0, LSL, 2));
- // hash = hash ^ (hash >> 4);
- eor(t0, t0, Operand(t0, LSR, 4));
- // hash = hash * 2057;
- mov(t1, Operand(2057));
- mul(t0, t0, t1);
- // hash = hash ^ (hash >> 16);
- eor(t0, t0, Operand(t0, LSR, 16));
+ GetNumberHash(t0, t1);
// Compute the capacity mask.
- ldr(t1, FieldMemOperand(elements, NumberDictionary::kCapacityOffset));
+ ldr(t1, FieldMemOperand(elements, SeededNumberDictionary::kCapacityOffset));
mov(t1, Operand(t1, ASR, kSmiTagSize)); // convert smi to int
sub(t1, t1, Operand(1));
@@ -1473,17 +1483,17 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
mov(t2, t0);
// Compute the masked index: (hash + i + i * i) & mask.
if (i > 0) {
- add(t2, t2, Operand(NumberDictionary::GetProbeOffset(i)));
+ add(t2, t2, Operand(SeededNumberDictionary::GetProbeOffset(i)));
}
and_(t2, t2, Operand(t1));
// Scale the index by multiplying by the element size.
- ASSERT(NumberDictionary::kEntrySize == 3);
+ ASSERT(SeededNumberDictionary::kEntrySize == 3);
add(t2, t2, Operand(t2, LSL, 1)); // t2 = t2 * 3
// Check if the key is identical to the name.
add(t2, elements, Operand(t2, LSL, kPointerSizeLog2));
- ldr(ip, FieldMemOperand(t2, NumberDictionary::kElementsStartOffset));
+ ldr(ip, FieldMemOperand(t2, SeededNumberDictionary::kElementsStartOffset));
cmp(key, Operand(ip));
if (i != kProbes - 1) {
b(eq, &done);
@@ -1496,14 +1506,14 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
// Check that the value is a normal property.
// t2: elements + (index * kPointerSize)
const int kDetailsOffset =
- NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
+ SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
ldr(t1, FieldMemOperand(t2, kDetailsOffset));
tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask)));
b(ne, miss);
// Get the value at the masked, scaled index and return.
const int kValueOffset =
- NumberDictionary::kElementsStartOffset + kPointerSize;
+ SeededNumberDictionary::kElementsStartOffset + kPointerSize;
ldr(result, FieldMemOperand(t2, kValueOffset));
}
@@ -1992,18 +2002,49 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
}
+void MacroAssembler::CompareMap(Register obj,
+ Register scratch,
+ Handle<Map> map,
+ Label* early_success,
+ CompareMapMode mode) {
+ ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
+ cmp(scratch, Operand(map));
+ if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
+ Map* transitioned_fast_element_map(
+ map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL));
+ ASSERT(transitioned_fast_element_map == NULL ||
+ map->elements_kind() != FAST_ELEMENTS);
+ if (transitioned_fast_element_map != NULL) {
+ b(eq, early_success);
+ cmp(scratch, Operand(Handle<Map>(transitioned_fast_element_map)));
+ }
+
+ Map* transitioned_double_map(
+ map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL));
+ ASSERT(transitioned_double_map == NULL ||
+ map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
+ if (transitioned_double_map != NULL) {
+ b(eq, early_success);
+ cmp(scratch, Operand(Handle<Map>(transitioned_double_map)));
+ }
+ }
+}
+
+
void MacroAssembler::CheckMap(Register obj,
Register scratch,
Handle<Map> map,
Label* fail,
- SmiCheckType smi_check_type) {
+ SmiCheckType smi_check_type,
+ CompareMapMode mode) {
if (smi_check_type == DO_SMI_CHECK) {
JumpIfSmi(obj, fail);
}
- ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
- mov(ip, Operand(map));
- cmp(scratch, ip);
+
+ Label success;
+ CompareMap(obj, scratch, map, &success, mode);
b(ne, fail);
+ bind(&success);
}
@@ -3460,7 +3501,7 @@ void MacroAssembler::EnsureNotWhite(
tst(mask_scratch, load_scratch);
b(ne, &done);
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// Check for impossible bit pattern.
Label ok;
// LSL may overflow, making the check conservative.
diff --git a/deps/v8/src/arm/macro-assembler-arm.h b/deps/v8/src/arm/macro-assembler-arm.h
index 392c2f7503..4b55a3b064 100644
--- a/deps/v8/src/arm/macro-assembler-arm.h
+++ b/deps/v8/src/arm/macro-assembler-arm.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -52,7 +52,7 @@ inline Operand SmiUntagOperand(Register object) {
// Give alias names to registers
const Register cp = { 8 }; // JavaScript context pointer
-const Register roots = { 10 }; // Roots array pointer.
+const Register kRootRegister = { 10 }; // Roots array pointer.
// Flags used for the AllocateInNewSpace functions.
enum AllocationFlags {
@@ -499,10 +499,16 @@ class MacroAssembler: public Assembler {
Register map,
Register scratch);
+ void InitializeRootRegister() {
+ ExternalReference roots_array_start =
+ ExternalReference::roots_array_start(isolate());
+ mov(kRootRegister, Operand(roots_array_start));
+ }
+
// ---------------------------------------------------------------------------
// JavaScript invokes
- // Setup call kind marking in ecx. The method takes ecx as an
+ // Set up call kind marking in ecx. The method takes ecx as an
// explicit first parameter to make the code more readable at the
// call sites.
void SetCallKind(Register dst, CallKind kind);
@@ -584,6 +590,7 @@ class MacroAssembler: public Assembler {
Register scratch,
Label* miss);
+ void GetNumberHash(Register t0, Register scratch);
void LoadFromNumberDictionary(Label* miss,
Register elements,
@@ -790,15 +797,26 @@ class MacroAssembler: public Assembler {
Register scratch4,
Label* fail);
- // Check if the map of an object is equal to a specified map (either
- // given directly or as an index into the root list) and branch to
- // label if not. Skip the smi check if not required (object is known
- // to be a heap object)
+ // Compare an object's map with the specified map and its transitioned
+ // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. Condition flags are
+ // set with result of map compare. If multiple map compares are required, the
+ // compare sequences branches to early_success.
+ void CompareMap(Register obj,
+ Register scratch,
+ Handle<Map> map,
+ Label* early_success,
+ CompareMapMode mode = REQUIRE_EXACT_MAP);
+
+ // Check if the map of an object is equal to a specified map and branch to
+ // label if not. Skip the smi check if not required (object is known to be a
+ // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
+ // against maps that are ElementsKind transition maps of the specificed map.
void CheckMap(Register obj,
Register scratch,
Handle<Map> map,
Label* fail,
- SmiCheckType smi_check_type);
+ SmiCheckType smi_check_type,
+ CompareMapMode mode = REQUIRE_EXACT_MAP);
void CheckMap(Register obj,
diff --git a/deps/v8/src/arm/simulator-arm.cc b/deps/v8/src/arm/simulator-arm.cc
index 0525529fde..1ae172c008 100644
--- a/deps/v8/src/arm/simulator-arm.cc
+++ b/deps/v8/src/arm/simulator-arm.cc
@@ -741,7 +741,7 @@ Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
isolate_->set_simulator_i_cache(i_cache_);
}
Initialize(isolate);
- // Setup simulator support first. Some of this information is needed to
+ // Set up simulator support first. Some of this information is needed to
// setup the architecture state.
size_t stack_size = 1 * 1024*1024; // allocate 1MB for stack
stack_ = reinterpret_cast<char*>(malloc(stack_size));
@@ -750,7 +750,7 @@ Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
break_pc_ = NULL;
break_instr_ = 0;
- // Setup architecture state.
+ // Set up architecture state.
// All registers are initialized to zero to start with.
for (int i = 0; i < num_registers; i++) {
registers_[i] = 0;
@@ -3324,7 +3324,7 @@ void Simulator::Execute() {
int32_t Simulator::Call(byte* entry, int argument_count, ...) {
va_list parameters;
va_start(parameters, argument_count);
- // Setup arguments
+ // Set up arguments
// First four arguments passed in registers.
ASSERT(argument_count >= 4);
@@ -3367,7 +3367,7 @@ int32_t Simulator::Call(byte* entry, int argument_count, ...) {
int32_t r10_val = get_register(r10);
int32_t r11_val = get_register(r11);
- // Setup the callee-saved registers with a known value. To be able to check
+ // Set up the callee-saved registers with a known value. To be able to check
// that they are preserved properly across JS execution.
int32_t callee_saved_value = icount_;
set_register(r4, callee_saved_value);
diff --git a/deps/v8/src/arm/stub-cache-arm.cc b/deps/v8/src/arm/stub-cache-arm.cc
index b6b2ee2f04..c3a82ff934 100644
--- a/deps/v8/src/arm/stub-cache-arm.cc
+++ b/deps/v8/src/arm/stub-cache-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -376,13 +376,9 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
// r0 : value
Label exit;
- // Check that the receiver isn't a smi.
- __ JumpIfSmi(receiver_reg, miss_label);
-
- // Check that the map of the receiver hasn't changed.
- __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
- __ cmp(scratch, Operand(Handle<Map>(object->map())));
- __ b(ne, miss_label);
+ // Check that the map of the object hasn't changed.
+ __ CheckMap(receiver_reg, scratch, Handle<Map>(object->map()), miss_label,
+ DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
@@ -1019,10 +1015,9 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
__ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
} else {
Handle<Map> current_map(current->map());
- __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
- __ cmp(scratch1, Operand(current_map));
- // Branch on the result of the map check.
- __ b(ne, miss);
+ __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK,
+ ALLOW_ELEMENT_TRANSITION_MAPS);
+
// Check access rights to the global object. This has to happen after
// the map check so that we know that the object is actually a global
// object.
@@ -1053,9 +1048,8 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
// Check the holder map.
- __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
- __ cmp(scratch1, Operand(Handle<Map>(current->map())));
- __ b(ne, miss);
+ __ CheckMap(reg, scratch1, Handle<Map>(current->map()), miss,
+ DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform security check for access to the global object.
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
@@ -1150,7 +1144,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
__ EnterExitFrame(false, kApiStackSpace);
// Create AccessorInfo instance on the stack above the exit frame with
- // scratch2 (internal::Object **args_) as the data.
+ // scratch2 (internal::Object** args_) as the data.
__ str(scratch2, MemOperand(sp, 1 * kPointerSize));
__ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo&
@@ -2411,7 +2405,7 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
__ str(r3, MemOperand(sp, argc * kPointerSize));
}
- // Setup the context (function already in r1).
+ // Set up the context (function already in r1).
__ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
// Jump to the cached code (tail call).
@@ -2472,13 +2466,9 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -----------------------------------
Label miss;
- // Check that the object isn't a smi.
- __ JumpIfSmi(r1, &miss);
-
// Check that the map of the object hasn't changed.
- __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
- __ cmp(r3, Operand(Handle<Map>(object->map())));
- __ b(ne, &miss);
+ __ CheckMap(r1, r3, Handle<Map>(object->map()), &miss,
+ DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
@@ -2520,13 +2510,9 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
// -----------------------------------
Label miss;
- // Check that the object isn't a smi.
- __ JumpIfSmi(r1, &miss);
-
// Check that the map of the object hasn't changed.
- __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
- __ cmp(r3, Operand(Handle<Map>(receiver->map())));
- __ b(ne, &miss);
+ __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss,
+ DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (receiver->IsJSGlobalProxy()) {
diff --git a/deps/v8/src/assembler.h b/deps/v8/src/assembler.h
index cec20fca07..8c705a84b4 100644
--- a/deps/v8/src/assembler.h
+++ b/deps/v8/src/assembler.h
@@ -371,7 +371,7 @@ class RelocInfo BASE_EMBEDDED {
// routines expect to access these pointers indirectly. The following
// location provides a place for these pointers to exist natually
// when accessed via the Iterator.
- Object *reconstructed_obj_ptr_;
+ Object* reconstructed_obj_ptr_;
// External-reference pointers are also split across instruction-pairs
// in mips, but are accessed via indirect pointers. This location
// provides a place for that pointer to exist naturally. Its address
diff --git a/deps/v8/src/atomicops_internals_x86_macosx.h b/deps/v8/src/atomicops_internals_x86_macosx.h
index 2bac006bdc..bfb02b3851 100644
--- a/deps/v8/src/atomicops_internals_x86_macosx.h
+++ b/deps/v8/src/atomicops_internals_x86_macosx.h
@@ -35,7 +35,7 @@
namespace v8 {
namespace internal {
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
Atomic32 prev_value;
@@ -49,7 +49,7 @@ inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
return prev_value;
}
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
Atomic32 new_value) {
Atomic32 old_value;
do {
@@ -59,12 +59,12 @@ inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
return old_value;
}
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr));
}
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));
}
@@ -73,7 +73,7 @@ inline void MemoryBarrier() {
OSMemoryBarrier();
}
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
Atomic32 prev_value;
@@ -87,7 +87,7 @@ inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
return prev_value;
}
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
return Acquire_CompareAndSwap(ptr, old_value, new_value);
@@ -97,12 +97,12 @@ inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
-inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
MemoryBarrier();
}
-inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
MemoryBarrier();
*ptr = value;
}
@@ -111,13 +111,13 @@ inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return *ptr;
}
-inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
Atomic32 value = *ptr;
MemoryBarrier();
return value;
}
-inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
MemoryBarrier();
return *ptr;
}
@@ -126,7 +126,7 @@ inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
// 64-bit implementation on 64-bit platform
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
Atomic64 prev_value;
@@ -140,7 +140,7 @@ inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
return prev_value;
}
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
Atomic64 new_value) {
Atomic64 old_value;
do {
@@ -150,17 +150,17 @@ inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
return old_value;
}
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
return OSAtomicAdd64(increment, const_cast<Atomic64*>(ptr));
}
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
return OSAtomicAdd64Barrier(increment, const_cast<Atomic64*>(ptr));
}
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
Atomic64 prev_value;
@@ -174,7 +174,7 @@ inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
return prev_value;
}
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
// The lib kern interface does not distinguish between
@@ -186,12 +186,12 @@ inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
*ptr = value;
}
-inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
*ptr = value;
MemoryBarrier();
}
-inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
MemoryBarrier();
*ptr = value;
}
@@ -200,13 +200,13 @@ inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
return *ptr;
}
-inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
Atomic64 value = *ptr;
MemoryBarrier();
return value;
}
-inline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
MemoryBarrier();
return *ptr;
}
@@ -264,7 +264,7 @@ inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
old_value, new_value);
}
-inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
+inline void NoBarrier_Store(volatile AtomicWord* ptr, AtomicWord value) {
NoBarrier_Store(
reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);
}
@@ -279,7 +279,7 @@ inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);
}
-inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
+inline AtomicWord NoBarrier_Load(volatile const AtomicWord* ptr) {
return NoBarrier_Load(
reinterpret_cast<volatile const AtomicWordCastType*>(ptr));
}
diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc
index d1bf975fb5..752b220e5b 100644
--- a/deps/v8/src/bootstrapper.cc
+++ b/deps/v8/src/bootstrapper.cc
@@ -264,13 +264,13 @@ class Genesis BASE_EMBEDDED {
Handle<Map> CreateStrictModeFunctionMap(
PrototypePropertyMode prototype_mode,
Handle<JSFunction> empty_function,
- Handle<FixedArray> arguments_callbacks,
- Handle<FixedArray> caller_callbacks);
+ Handle<AccessorPair> arguments_callbacks,
+ Handle<AccessorPair> caller_callbacks);
Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
PrototypePropertyMode propertyMode,
- Handle<FixedArray> arguments,
- Handle<FixedArray> caller);
+ Handle<AccessorPair> arguments,
+ Handle<AccessorPair> caller);
static bool CompileBuiltin(Isolate* isolate, int index);
static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
@@ -378,7 +378,9 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
} else {
attributes = DONT_ENUM;
}
- SetLocalPropertyNoThrow(target, symbol, function, attributes);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ target, symbol, function, attributes));
if (is_ecma_native) {
function->shared()->set_instance_class_name(*symbol);
}
@@ -538,8 +540,8 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
PrototypePropertyMode prototypeMode,
- Handle<FixedArray> arguments,
- Handle<FixedArray> caller) {
+ Handle<AccessorPair> arguments,
+ Handle<AccessorPair> caller) {
Handle<DescriptorArray> descriptors =
factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
? 4
@@ -600,7 +602,7 @@ Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() {
throw_type_error_function->shared()->set_code(*code);
throw_type_error_function->shared()->DontAdaptArguments();
- PreventExtensions(throw_type_error_function);
+ JSObject::PreventExtensions(throw_type_error_function);
}
return throw_type_error_function;
}
@@ -609,8 +611,8 @@ Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() {
Handle<Map> Genesis::CreateStrictModeFunctionMap(
PrototypePropertyMode prototype_mode,
Handle<JSFunction> empty_function,
- Handle<FixedArray> arguments_callbacks,
- Handle<FixedArray> caller_callbacks) {
+ Handle<AccessorPair> arguments_callbacks,
+ Handle<AccessorPair> caller_callbacks) {
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Handle<DescriptorArray> descriptors =
ComputeStrictFunctionInstanceDescriptor(prototype_mode,
@@ -627,8 +629,8 @@ void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
// Create the callbacks arrays for ThrowTypeError functions.
// The get/set callacks are filled in after the maps are created below.
Factory* factory = empty->GetIsolate()->factory();
- Handle<FixedArray> arguments = factory->NewFixedArray(2, TENURED);
- Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
+ Handle<AccessorPair> arguments(factory->NewAccessorPair());
+ Handle<AccessorPair> caller(factory->NewAccessorPair());
// Allocate map for the strict mode function instances.
Handle<Map> strict_mode_function_instance_map =
@@ -663,11 +665,11 @@ void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
Handle<JSFunction> throw_function =
GetThrowTypeErrorFunction();
- // Complete the callback fixed arrays.
- arguments->set(0, *throw_function);
- arguments->set(1, *throw_function);
- caller->set(0, *throw_function);
- caller->set(1, *throw_function);
+ // Complete the callbacks.
+ arguments->set_getter(*throw_function);
+ arguments->set_setter(*throw_function);
+ caller->set_getter(*throw_function);
+ caller->set_setter(*throw_function);
}
@@ -753,11 +755,10 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
Handle<JSObject> prototype =
Handle<JSObject>(
JSObject::cast(js_global_function->instance_prototype()));
- SetLocalPropertyNoThrow(
- prototype,
- factory()->constructor_symbol(),
- isolate()->object_function(),
- NONE);
+ CHECK_NOT_EMPTY_HANDLE(isolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ prototype, factory()->constructor_symbol(),
+ isolate()->object_function(), NONE));
} else {
Handle<FunctionTemplateInfo> js_global_constructor(
FunctionTemplateInfo::cast(js_global_template->constructor()));
@@ -834,7 +835,7 @@ void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
factory()->LookupAsciiSymbol("global"),
inner_global,
attributes);
- // Setup the reference from the global object to the builtins object.
+ // Set up the reference from the global object to the builtins object.
JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
TransferNamedProperties(inner_global_from_snapshot, inner_global);
TransferIndexedProperties(inner_global_from_snapshot, inner_global);
@@ -863,8 +864,10 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Heap* heap = isolate->heap();
Handle<String> object_name = Handle<String>(heap->Object_symbol());
- SetLocalPropertyNoThrow(inner_global, object_name,
- isolate->object_function(), DONT_ENUM);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ inner_global, object_name,
+ isolate->object_function(), DONT_ENUM));
Handle<JSObject> global = Handle<JSObject>(global_context()->global());
@@ -1046,14 +1049,15 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
{ // -- J S O N
Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
- Handle<JSFunction> cons = factory->NewFunction(
- name,
- factory->the_hole_value());
+ Handle<JSFunction> cons = factory->NewFunction(name,
+ factory->the_hole_value());
cons->SetInstancePrototype(global_context()->initial_object_prototype());
cons->SetInstanceClassName(*name);
Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
ASSERT(json_object->IsJSObject());
- SetLocalPropertyNoThrow(global, name, json_object, DONT_ENUM);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ global, name, json_object, DONT_ENUM));
global_context()->set_json_object(*json_object);
}
@@ -1083,12 +1087,14 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
global_context()->set_arguments_boilerplate(*result);
// Note: length must be added as the first property and
// callee must be added as the second property.
- SetLocalPropertyNoThrow(result, factory->length_symbol(),
- factory->undefined_value(),
- DONT_ENUM);
- SetLocalPropertyNoThrow(result, factory->callee_symbol(),
- factory->undefined_value(),
- DONT_ENUM);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ result, factory->length_symbol(),
+ factory->undefined_value(), DONT_ENUM));
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ result, factory->callee_symbol(),
+ factory->undefined_value(), DONT_ENUM));
#ifdef DEBUG
LookupResult lookup(isolate);
@@ -1136,17 +1142,17 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
// Create the ThrowTypeError functions.
- Handle<FixedArray> callee = factory->NewFixedArray(2, TENURED);
- Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
+ Handle<AccessorPair> callee = factory->NewAccessorPair();
+ Handle<AccessorPair> caller = factory->NewAccessorPair();
Handle<JSFunction> throw_function =
GetThrowTypeErrorFunction();
// Install the ThrowTypeError functions.
- callee->set(0, *throw_function);
- callee->set(1, *throw_function);
- caller->set(0, *throw_function);
- caller->set(1, *throw_function);
+ callee->set_getter(*throw_function);
+ callee->set_setter(*throw_function);
+ caller->set_getter(*throw_function);
+ caller->set_setter(*throw_function);
// Create the descriptor array for the arguments object.
Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
@@ -1183,9 +1189,10 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
global_context()->set_strict_mode_arguments_boilerplate(*result);
// Add length property only for strict mode boilerplate.
- SetLocalPropertyNoThrow(result, factory->length_symbol(),
- factory->undefined_value(),
- DONT_ENUM);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ result, factory->length_symbol(),
+ factory->undefined_value(), DONT_ENUM));
#ifdef DEBUG
LookupResult lookup(isolate);
@@ -1353,7 +1360,7 @@ bool Genesis::CompileScriptCached(Vector<const char> name,
if (cache != NULL) cache->Add(name, function_info);
}
- // Setup the function context. Conceptually, we should clone the
+ // Set up the function context. Conceptually, we should clone the
// function before overwriting the context but since we're in a
// single-threaded environment it is not strictly necessary.
ASSERT(top_context->IsGlobalContext());
@@ -1440,7 +1447,7 @@ bool Genesis::InstallNatives() {
builtins->set_global_context(*global_context());
builtins->set_global_receiver(*builtins);
- // Setup the 'global' properties of the builtins object. The
+ // Set up the 'global' properties of the builtins object. The
// 'global' property that refers to the global object is the only
// way to get from code running in the builtins context to the
// global object.
@@ -1448,9 +1455,11 @@ bool Genesis::InstallNatives() {
static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
Handle<String> global_symbol = factory()->LookupAsciiSymbol("global");
Handle<Object> global_obj(global_context()->global());
- SetLocalPropertyNoThrow(builtins, global_symbol, global_obj, attributes);
+ CHECK_NOT_EMPTY_HANDLE(isolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ builtins, global_symbol, global_obj, attributes));
- // Setup the reference from the global object to the builtins object.
+ // Set up the reference from the global object to the builtins object.
JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
// Create a bridge function that has context in the global context.
@@ -1674,7 +1683,7 @@ bool Genesis::InstallNatives() {
InstallNativeFunctions();
// Store the map for the string prototype after the natives has been compiled
- // and the String function has been setup.
+ // and the String function has been set up.
Handle<JSFunction> string_function(global_context()->string_function());
ASSERT(JSObject::cast(
string_function->initial_map()->prototype())->HasFastProperties());
@@ -1911,25 +1920,28 @@ bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
- Factory* factory = global_context->GetIsolate()->factory();
+ Isolate* isolate = global_context->GetIsolate();
+ Factory* factory = isolate->factory();
HandleScope scope;
- Handle<JSGlobalObject> js_global(
- JSGlobalObject::cast(global_context->global()));
+ Handle<JSGlobalObject> global(JSGlobalObject::cast(global_context->global()));
// Expose the natives in global if a name for it is specified.
if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
- Handle<String> natives_string =
- factory->LookupAsciiSymbol(FLAG_expose_natives_as);
- SetLocalPropertyNoThrow(js_global, natives_string,
- Handle<JSObject>(js_global->builtins()), DONT_ENUM);
+ Handle<String> natives = factory->LookupAsciiSymbol(FLAG_expose_natives_as);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ global, natives,
+ Handle<JSObject>(global->builtins()),
+ DONT_ENUM));
}
- Handle<Object> Error = GetProperty(js_global, "Error");
+ Handle<Object> Error = GetProperty(global, "Error");
if (Error->IsJSObject()) {
Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit");
- SetLocalPropertyNoThrow(Handle<JSObject>::cast(Error),
- name,
- Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
- NONE);
+ Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit));
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ Handle<JSObject>::cast(Error), name,
+ stack_trace_limit, NONE));
}
#ifdef ENABLE_DEBUGGER_SUPPORT
@@ -1948,7 +1960,9 @@ void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
Handle<String> debug_string =
factory->LookupAsciiSymbol(FLAG_expose_debug_as);
Handle<Object> global_proxy(debug->debug_context()->global_proxy());
- SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ global, debug_string, global_proxy, DONT_ENUM));
}
#endif
}
@@ -2164,7 +2178,9 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
Handle<String> key = Handle<String>(descs->GetKey(i));
int index = descs->GetFieldIndex(i);
Handle<Object> value = Handle<Object>(from->FastPropertyAt(index));
- SetLocalPropertyNoThrow(to, key, value, details.attributes());
+ CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ to, key, value, details.attributes()));
break;
}
case CONSTANT_FUNCTION: {
@@ -2172,7 +2188,9 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
Handle<String> key = Handle<String>(descs->GetKey(i));
Handle<JSFunction> fun =
Handle<JSFunction>(descs->GetConstantFunction(i));
- SetLocalPropertyNoThrow(to, key, fun, details.attributes());
+ CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ to, key, fun, details.attributes()));
break;
}
case CALLBACKS: {
@@ -2187,7 +2205,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
Handle<Object> callbacks(descs->GetCallbacksObject(i));
PropertyDetails d =
PropertyDetails(details.attributes(), CALLBACKS, details.index());
- SetNormalizedProperty(to, key, callbacks, d);
+ JSObject::SetNormalizedProperty(to, key, callbacks, d);
break;
}
case MAP_TRANSITION:
@@ -2224,7 +2242,9 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
value = Handle<Object>(JSGlobalPropertyCell::cast(*value)->value());
}
PropertyDetails details = properties->DetailsAt(i);
- SetLocalPropertyNoThrow(to, key, value, details.attributes());
+ CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ to, key, value, details.attributes()));
}
}
}
diff --git a/deps/v8/src/bootstrapper.h b/deps/v8/src/bootstrapper.h
index abf61b9fe5..101c2e1b1f 100644
--- a/deps/v8/src/bootstrapper.h
+++ b/deps/v8/src/bootstrapper.h
@@ -88,7 +88,7 @@ class SourceCodeCache BASE_EMBEDDED {
// context.
class Bootstrapper {
public:
- // Requires: Heap::Setup has been called.
+ // Requires: Heap::SetUp has been called.
void Initialize(bool create_heap_objects);
void TearDown();
diff --git a/deps/v8/src/builtins.cc b/deps/v8/src/builtins.cc
index 916799499f..69e5161ce5 100644
--- a/deps/v8/src/builtins.cc
+++ b/deps/v8/src/builtins.cc
@@ -1719,7 +1719,7 @@ void Builtins::InitBuiltinFunctionTable() {
#undef DEF_FUNCTION_PTR_A
}
-void Builtins::Setup(bool create_heap_objects) {
+void Builtins::SetUp(bool create_heap_objects) {
ASSERT(!initialized_);
Isolate* isolate = Isolate::Current();
Heap* heap = isolate->heap();
diff --git a/deps/v8/src/builtins.h b/deps/v8/src/builtins.h
index 6a84f2ddd1..f20d97df5b 100644
--- a/deps/v8/src/builtins.h
+++ b/deps/v8/src/builtins.h
@@ -265,7 +265,7 @@ class Builtins {
// Generate all builtin code objects. Should be called once during
// isolate initialization.
- void Setup(bool create_heap_objects);
+ void SetUp(bool create_heap_objects);
void TearDown();
// Garbage collection support.
diff --git a/deps/v8/src/code-stubs.cc b/deps/v8/src/code-stubs.cc
index 85410c3cc8..5fa9a2b5c0 100644
--- a/deps/v8/src/code-stubs.cc
+++ b/deps/v8/src/code-stubs.cc
@@ -40,7 +40,7 @@ namespace internal {
bool CodeStub::FindCodeInCache(Code** code_out) {
Heap* heap = Isolate::Current()->heap();
int index = heap->code_stubs()->FindEntry(GetKey());
- if (index != NumberDictionary::kNotFound) {
+ if (index != UnseededNumberDictionary::kNotFound) {
*code_out = Code::cast(heap->code_stubs()->ValueAt(index));
return true;
}
@@ -132,9 +132,9 @@ Handle<Code> CodeStub::GetCode() {
AddToSpecialCache(new_object);
} else {
// Update the dictionary and the root in Heap.
- Handle<NumberDictionary> dict =
+ Handle<UnseededNumberDictionary> dict =
factory->DictionaryAtNumberPut(
- Handle<NumberDictionary>(heap->code_stubs()),
+ Handle<UnseededNumberDictionary>(heap->code_stubs()),
GetKey(),
new_object);
heap->public_set_code_stubs(*dict);
diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc
index d2a4a0bfdc..362273e27a 100644
--- a/deps/v8/src/compiler.cc
+++ b/deps/v8/src/compiler.cc
@@ -628,7 +628,7 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
// scope info. Please note, that the order of the shared function
// info initialization is important since set_scope_info might
// trigger a GC, causing the ASSERT below to be invalid if the code
- // was flushed. By settting the code object last we avoid this.
+ // was flushed. By setting the code object last we avoid this.
Handle<ScopeInfo> scope_info = ScopeInfo::Create(info->scope());
shared->set_scope_info(*scope_info);
shared->set_code(*code);
diff --git a/deps/v8/src/cpu-profiler.cc b/deps/v8/src/cpu-profiler.cc
index d74c034ac5..2bd62ad390 100644
--- a/deps/v8/src/cpu-profiler.cc
+++ b/deps/v8/src/cpu-profiler.cc
@@ -493,7 +493,7 @@ void CpuProfiler::StartProcessorIfNotStarted() {
NoBarrier_Store(&is_profiling_, true);
processor_->Start();
// Enumerate stuff we already have in the heap.
- if (isolate->heap()->HasBeenSetup()) {
+ if (isolate->heap()->HasBeenSetUp()) {
if (!FLAG_prof_browser_mode) {
bool saved_log_code_flag = FLAG_log_code;
FLAG_log_code = true;
@@ -562,7 +562,7 @@ void CpuProfiler::StopProcessor() {
}
-void CpuProfiler::Setup() {
+void CpuProfiler::SetUp() {
Isolate* isolate = Isolate::Current();
if (isolate->cpu_profiler() == NULL) {
isolate->set_cpu_profiler(new CpuProfiler());
diff --git a/deps/v8/src/cpu-profiler.h b/deps/v8/src/cpu-profiler.h
index a71c0e0ab4..3f4fec5f45 100644
--- a/deps/v8/src/cpu-profiler.h
+++ b/deps/v8/src/cpu-profiler.h
@@ -204,7 +204,7 @@ namespace internal {
// TODO(isolates): isolatify this class.
class CpuProfiler {
public:
- static void Setup();
+ static void SetUp();
static void TearDown();
static void StartProfiling(const char* title);
@@ -230,11 +230,11 @@ class CpuProfiler {
Code* code, String* name);
static void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
- SharedFunctionInfo *shared,
+ SharedFunctionInfo* shared,
String* name);
static void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code,
- SharedFunctionInfo *shared,
+ SharedFunctionInfo* shared,
String* source, int line);
static void CodeCreateEvent(Logger::LogEventsAndTags tag,
Code* code, int args_count);
diff --git a/deps/v8/src/cpu.h b/deps/v8/src/cpu.h
index 2525484a01..247af71aa3 100644
--- a/deps/v8/src/cpu.h
+++ b/deps/v8/src/cpu.h
@@ -53,7 +53,7 @@ namespace internal {
class CPU : public AllStatic {
public:
// Initializes the cpu architecture support. Called once at VM startup.
- static void Setup();
+ static void SetUp();
static bool SupportsCrankshaft();
diff --git a/deps/v8/src/d8-debug.cc b/deps/v8/src/d8-debug.cc
index 8fbc876dab..1cbc0b39a0 100644
--- a/deps/v8/src/d8-debug.cc
+++ b/deps/v8/src/d8-debug.cc
@@ -169,7 +169,7 @@ void RemoteDebugger::Run() {
bool ok;
// Make sure that socket support is initialized.
- ok = i::Socket::Setup();
+ ok = i::Socket::SetUp();
if (!ok) {
printf("Unable to initialize socket support %d\n", i::Socket::LastError());
return;
diff --git a/deps/v8/src/d8.cc b/deps/v8/src/d8.cc
index ad850f5ee7..97828a4ac4 100644
--- a/deps/v8/src/d8.cc
+++ b/deps/v8/src/d8.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -281,63 +281,161 @@ Handle<Value> Shell::Load(const Arguments& args) {
return Undefined();
}
+static size_t convertToUint(Local<Value> value_in, TryCatch* try_catch) {
+ if (value_in->IsUint32()) {
+ return value_in->Uint32Value();
+ }
+
+ Local<Value> number = value_in->ToNumber();
+ if (try_catch->HasCaught()) return 0;
+
+ ASSERT(number->IsNumber());
+ Local<Int32> int32 = number->ToInt32();
+ if (try_catch->HasCaught() || int32.IsEmpty()) return 0;
+
+ int32_t raw_value = int32->Int32Value();
+ if (try_catch->HasCaught()) return 0;
+
+ if (raw_value < 0) {
+ ThrowException(String::New("Array length must not be negative."));
+ return 0;
+ }
+
+ static const int kMaxLength = 0x3fffffff;
+#ifndef V8_SHARED
+ ASSERT(kMaxLength == i::ExternalArray::kMaxLength);
+#endif // V8_SHARED
+ if (raw_value > static_cast<int32_t>(kMaxLength)) {
+ ThrowException(
+ String::New("Array length exceeds maximum length."));
+ }
+ return static_cast<size_t>(raw_value);
+}
+
+
+const char kArrayBufferReferencePropName[] = "_is_array_buffer_";
+const char kArrayBufferMarkerPropName[] = "_array_buffer_ref_";
+
Handle<Value> Shell::CreateExternalArray(const Arguments& args,
ExternalArrayType type,
size_t element_size) {
+ TryCatch try_catch;
+ bool is_array_buffer_construct = element_size == 0;
+ if (is_array_buffer_construct) {
+ type = v8::kExternalByteArray;
+ element_size = 1;
+ }
ASSERT(element_size == 1 || element_size == 2 || element_size == 4 ||
element_size == 8);
- if (args.Length() != 1) {
+ if (args.Length() == 0) {
return ThrowException(
- String::New("Array constructor needs one parameter."));
+ String::New("Array constructor must have at least one "
+ "parameter."));
}
- static const int kMaxLength = 0x3fffffff;
-#ifndef V8_SHARED
- ASSERT(kMaxLength == i::ExternalArray::kMaxLength);
-#endif // V8_SHARED
- size_t length = 0;
- TryCatch try_catch;
- if (args[0]->IsUint32()) {
- length = args[0]->Uint32Value();
- } else {
- Local<Number> number = args[0]->ToNumber();
- if (number.IsEmpty()) {
- ASSERT(try_catch.HasCaught());
- return try_catch.Exception();
+ bool first_arg_is_array_buffer =
+ args[0]->IsObject() &&
+ args[0]->ToObject()->Get(
+ String::New(kArrayBufferMarkerPropName))->IsTrue();
+ // Currently, only the following constructors are supported:
+ // TypedArray(unsigned long length)
+ // TypedArray(ArrayBuffer buffer,
+ // optional unsigned long byteOffset,
+ // optional unsigned long length)
+ if (args.Length() > 3) {
+ return ThrowException(
+ String::New("Array constructor from ArrayBuffer must "
+ "have 1-3 parameters."));
+ }
+
+ Local<Value> length_value = (args.Length() < 3)
+ ? (first_arg_is_array_buffer
+ ? args[0]->ToObject()->Get(String::New("length"))
+ : args[0])
+ : args[2];
+ size_t length = convertToUint(length_value, &try_catch);
+ if (try_catch.HasCaught()) return try_catch.Exception();
+
+ void* data = NULL;
+ size_t offset = 0;
+
+ Handle<Object> array = Object::New();
+ if (first_arg_is_array_buffer) {
+ Handle<Object> derived_from = args[0]->ToObject();
+ data = derived_from->GetIndexedPropertiesExternalArrayData();
+
+ size_t array_buffer_length = convertToUint(
+ derived_from->Get(String::New("length")),
+ &try_catch);
+ if (try_catch.HasCaught()) return try_catch.Exception();
+
+ if (data == NULL && array_buffer_length != 0) {
+ return ThrowException(
+ String::New("ArrayBuffer doesn't have data"));
}
- ASSERT(number->IsNumber());
- Local<Int32> int32 = number->ToInt32();
- if (int32.IsEmpty()) {
- if (try_catch.HasCaught()) {
- return try_catch.Exception();
+
+ if (args.Length() > 1) {
+ offset = convertToUint(args[1], &try_catch);
+ if (try_catch.HasCaught()) return try_catch.Exception();
+
+ // The given byteOffset must be a multiple of the element size of the
+ // specific type, otherwise an exception is raised.
+ if (offset % element_size != 0) {
+ return ThrowException(
+ String::New("offset must be multiple of element_size"));
}
}
- int32_t raw_length = int32->Int32Value();
- if (try_catch.HasCaught()) {
- return try_catch.Exception();
+
+ if (offset > array_buffer_length) {
+ return ThrowException(
+ String::New("byteOffset must be less than ArrayBuffer length."));
}
- if (raw_length < 0) {
- return ThrowException(String::New("Array length must not be negative."));
+
+ if (args.Length() == 2) {
+ // If length is not explicitly specified, the length of the ArrayBuffer
+ // minus the byteOffset must be a multiple of the element size of the
+ // specific type, or an exception is raised.
+ length = array_buffer_length - offset;
+ }
+
+ if (args.Length() != 3) {
+ if (length % element_size != 0) {
+ return ThrowException(
+ String::New("ArrayBuffer length minus the byteOffset must be a "
+ "multiple of the element size"));
+ }
+ length /= element_size;
}
- if (raw_length > static_cast<int32_t>(kMaxLength)) {
+
+ // If a given byteOffset and length references an area beyond the end of
+ // the ArrayBuffer an exception is raised.
+ if (offset + (length * element_size) > array_buffer_length) {
return ThrowException(
- String::New("Array length exceeds maximum length."));
+ String::New("length references an area beyond the end of the "
+ "ArrayBuffer"));
}
- length = static_cast<size_t>(raw_length);
- }
- if (length > static_cast<size_t>(kMaxLength)) {
- return ThrowException(String::New("Array length exceeds maximum length."));
+
+ // Hold a reference to the ArrayBuffer so its buffer doesn't get collected.
+ array->Set(String::New(kArrayBufferReferencePropName), args[0], ReadOnly);
}
- void* data = calloc(length, element_size);
- if (data == NULL) {
- return ThrowException(String::New("Memory allocation failed."));
+
+ if (is_array_buffer_construct) {
+ array->Set(String::New(kArrayBufferMarkerPropName), True(), ReadOnly);
}
- Handle<Object> array = Object::New();
+
Persistent<Object> persistent_array = Persistent<Object>::New(array);
persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
persistent_array.MarkIndependent();
- array->SetIndexedPropertiesToExternalArrayData(data, type,
- static_cast<int>(length));
+ if (data == NULL && length != 0) {
+ data = calloc(length, element_size);
+ if (data == NULL) {
+ return ThrowException(String::New("Memory allocation failed."));
+ }
+ }
+
+ array->SetIndexedPropertiesToExternalArrayData(
+ reinterpret_cast<uint8_t*>(data) + offset, type,
+ static_cast<int>(length));
array->Set(String::New("length"),
Int32::New(static_cast<int32_t>(length)), ReadOnly);
array->Set(String::New("BYTES_PER_ELEMENT"),
@@ -347,11 +445,22 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
- free(data);
+ HandleScope scope;
+ Handle<String> prop_name = String::New(kArrayBufferReferencePropName);
+ Handle<Object> converted_object = object->ToObject();
+ Local<Value> prop_value = converted_object->Get(prop_name);
+ if (data != NULL && !prop_value->IsObject()) {
+ free(data);
+ }
object.Dispose();
}
+Handle<Value> Shell::ArrayBuffer(const Arguments& args) {
+ return CreateExternalArray(args, v8::kExternalByteArray, 0);
+}
+
+
Handle<Value> Shell::Int8Array(const Arguments& args) {
return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
}
@@ -693,6 +802,8 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate() {
FunctionTemplate::New(DisableProfiler));
// Bind the handlers for external arrays.
+ global_template->Set(String::New("ArrayBuffer"),
+ FunctionTemplate::New(ArrayBuffer));
global_template->Set(String::New("Int8Array"),
FunctionTemplate::New(Int8Array));
global_template->Set(String::New("Uint8Array"),
diff --git a/deps/v8/src/d8.h b/deps/v8/src/d8.h
index 15d8d5d50f..6c7733ccfa 100644
--- a/deps/v8/src/d8.h
+++ b/deps/v8/src/d8.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -289,6 +289,7 @@ class Shell : public i::AllStatic {
static Handle<Value> Read(const Arguments& args);
static Handle<Value> ReadLine(const Arguments& args);
static Handle<Value> Load(const Arguments& args);
+ static Handle<Value> ArrayBuffer(const Arguments& args);
static Handle<Value> Int8Array(const Arguments& args);
static Handle<Value> Uint8Array(const Arguments& args);
static Handle<Value> Int16Array(const Arguments& args);
diff --git a/deps/v8/src/debug-debugger.js b/deps/v8/src/debug-debugger.js
index 8cbe0b362c..120a297007 100644
--- a/deps/v8/src/debug-debugger.js
+++ b/deps/v8/src/debug-debugger.js
@@ -1547,7 +1547,7 @@ DebugCommandProcessor.prototype.continueRequest_ = function(request, response) {
}
}
- // Setup the VM for stepping.
+ // Set up the VM for stepping.
this.exec_state_.prepareStep(action, count);
}
diff --git a/deps/v8/src/debug.cc b/deps/v8/src/debug.cc
index 24e17823d8..ffba7821ca 100644
--- a/deps/v8/src/debug.cc
+++ b/deps/v8/src/debug.cc
@@ -682,7 +682,7 @@ void ScriptCache::HandleWeakScript(v8::Persistent<v8::Value> obj, void* data) {
}
-void Debug::Setup(bool create_heap_objects) {
+void Debug::SetUp(bool create_heap_objects) {
ThreadInit();
if (create_heap_objects) {
// Get code to handle debug break on return.
@@ -827,8 +827,8 @@ bool Debug::Load() {
Handle<GlobalObject> global = Handle<GlobalObject>(context->global());
RETURN_IF_EMPTY_HANDLE_VALUE(
isolate_,
- SetProperty(global, key, Handle<Object>(global->builtins()),
- NONE, kNonStrictMode),
+ JSReceiver::SetProperty(global, key, Handle<Object>(global->builtins()),
+ NONE, kNonStrictMode),
false);
// Compile the JavaScript for the debugger in the debugger context.
@@ -1213,7 +1213,7 @@ void Debug::ClearAllBreakPoints() {
void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
PrepareForBreakPoints();
- // Make sure the function has setup the debug info.
+ // Make sure the function has set up the debug info.
if (!EnsureDebugInfo(shared)) {
// Return if we failed to retrieve the debug info.
return;
@@ -2855,7 +2855,7 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
command.Dispose();
// Return from debug event processing if either the VM is put into the
- // runnning state (through a continue command) or auto continue is active
+ // running state (through a continue command) or auto continue is active
// and there are no more commands queued.
if (running && !HasCommands()) {
return;
@@ -3065,7 +3065,7 @@ bool Debugger::StartAgent(const char* name, int port,
v8::Debug::DebugBreak();
}
- if (Socket::Setup()) {
+ if (Socket::SetUp()) {
if (agent_ == NULL) {
agent_ = new DebuggerAgent(name, port);
agent_->Start();
diff --git a/deps/v8/src/debug.h b/deps/v8/src/debug.h
index a39d8013e4..582aadae8d 100644
--- a/deps/v8/src/debug.h
+++ b/deps/v8/src/debug.h
@@ -178,7 +178,9 @@ class ScriptCache : private HashMap {
private:
// Calculate the hash value from the key (script id).
- static uint32_t Hash(int key) { return ComputeIntegerHash(key); }
+ static uint32_t Hash(int key) {
+ return ComputeIntegerHash(key, v8::internal::kZeroHashSeed);
+ }
// Scripts match if their keys (script id) match.
static bool ScriptMatch(void* key1, void* key2) { return key1 == key2; }
@@ -222,7 +224,7 @@ class DebugInfoListNode {
// DebugInfo.
class Debug {
public:
- void Setup(bool create_heap_objects);
+ void SetUp(bool create_heap_objects);
bool Load();
void Unload();
bool IsLoaded() { return !debug_context_.is_null(); }
diff --git a/deps/v8/src/elements.cc b/deps/v8/src/elements.cc
index fd2b6d248a..e54ec62691 100644
--- a/deps/v8/src/elements.cc
+++ b/deps/v8/src/elements.cc
@@ -549,11 +549,11 @@ class PixelElementsAccessor
class DictionaryElementsAccessor
: public ElementsAccessorBase<DictionaryElementsAccessor,
- NumberDictionary> {
+ SeededNumberDictionary> {
public:
// Adjusts the length of the dictionary backing store and returns the new
// length according to ES5 section 15.4.5.2 behavior.
- static MaybeObject* SetLengthWithoutNormalize(NumberDictionary* dict,
+ static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict,
JSArray* array,
Object* length_object,
uint32_t length) {
@@ -619,9 +619,10 @@ class DictionaryElementsAccessor
if (is_arguments) {
backing_store = FixedArray::cast(backing_store->get(1));
}
- NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(backing_store);
int entry = dictionary->FindEntry(key);
- if (entry != NumberDictionary::kNotFound) {
+ if (entry != SeededNumberDictionary::kNotFound) {
Object* result = dictionary->DeleteProperty(entry, mode);
if (result == heap->true_value()) {
MaybeObject* maybe_elements = dictionary->Shrink(key);
@@ -654,7 +655,7 @@ class DictionaryElementsAccessor
protected:
friend class ElementsAccessorBase<DictionaryElementsAccessor,
- NumberDictionary>;
+ SeededNumberDictionary>;
virtual MaybeObject* Delete(JSObject* obj,
uint32_t key,
@@ -662,12 +663,12 @@ class DictionaryElementsAccessor
return DeleteCommon(obj, key, mode);
}
- static MaybeObject* Get(NumberDictionary* backing_store,
+ static MaybeObject* Get(SeededNumberDictionary* backing_store,
uint32_t key,
JSObject* obj,
Object* receiver) {
int entry = backing_store->FindEntry(key);
- if (entry != NumberDictionary::kNotFound) {
+ if (entry != SeededNumberDictionary::kNotFound) {
Object* element = backing_store->ValueAt(entry);
PropertyDetails details = backing_store->DetailsAt(entry);
if (details.type() == CALLBACKS) {
@@ -682,7 +683,7 @@ class DictionaryElementsAccessor
return obj->GetHeap()->the_hole_value();
}
- static uint32_t GetKeyForIndex(NumberDictionary* dict,
+ static uint32_t GetKeyForIndex(SeededNumberDictionary* dict,
uint32_t index) {
Object* key = dict->KeyAt(index);
return Smi::cast(key)->value();
@@ -895,7 +896,7 @@ MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, BackingStoreClass>::
if (length->IsNumber()) {
uint32_t value;
if (length->ToArrayIndex(&value)) {
- NumberDictionary* dictionary;
+ SeededNumberDictionary* dictionary;
MaybeObject* maybe_object = array->NormalizeElements();
if (!maybe_object->To(&dictionary)) return maybe_object;
Object* new_length;
diff --git a/deps/v8/src/execution.cc b/deps/v8/src/execution.cc
index b16e7396ad..125241ceec 100644
--- a/deps/v8/src/execution.cc
+++ b/deps/v8/src/execution.cc
@@ -845,13 +845,13 @@ Object* Execution::DebugBreakHelper() {
// Clear the debug break request flag.
isolate->stack_guard()->Continue(DEBUGBREAK);
- ProcessDebugMesssages(debug_command_only);
+ ProcessDebugMessages(debug_command_only);
// Return to continue execution.
return isolate->heap()->undefined_value();
}
-void Execution::ProcessDebugMesssages(bool debug_command_only) {
+void Execution::ProcessDebugMessages(bool debug_command_only) {
Isolate* isolate = Isolate::Current();
// Clear the debug command request flag.
isolate->stack_guard()->Continue(DEBUGCOMMAND);
diff --git a/deps/v8/src/execution.h b/deps/v8/src/execution.h
index f2d17d0792..014736ee88 100644
--- a/deps/v8/src/execution.h
+++ b/deps/v8/src/execution.h
@@ -136,7 +136,7 @@ class Execution : public AllStatic {
Handle<Object> is_global);
#ifdef ENABLE_DEBUGGER_SUPPORT
static Object* DebugBreakHelper();
- static void ProcessDebugMesssages(bool debug_command_only);
+ static void ProcessDebugMessages(bool debug_command_only);
#endif
// If the stack guard is triggered, but it is not an actual
diff --git a/deps/v8/src/factory.cc b/deps/v8/src/factory.cc
index c2976a577a..0b796350d4 100644
--- a/deps/v8/src/factory.cc
+++ b/deps/v8/src/factory.cc
@@ -77,11 +77,21 @@ Handle<StringDictionary> Factory::NewStringDictionary(int at_least_space_for) {
}
-Handle<NumberDictionary> Factory::NewNumberDictionary(int at_least_space_for) {
+Handle<SeededNumberDictionary> Factory::NewSeededNumberDictionary(
+ int at_least_space_for) {
ASSERT(0 <= at_least_space_for);
CALL_HEAP_FUNCTION(isolate(),
- NumberDictionary::Allocate(at_least_space_for),
- NumberDictionary);
+ SeededNumberDictionary::Allocate(at_least_space_for),
+ SeededNumberDictionary);
+}
+
+
+Handle<UnseededNumberDictionary> Factory::NewUnseededNumberDictionary(
+ int at_least_space_for) {
+ ASSERT(0 <= at_least_space_for);
+ CALL_HEAP_FUNCTION(isolate(),
+ UnseededNumberDictionary::Allocate(at_least_space_for),
+ UnseededNumberDictionary);
}
@@ -131,6 +141,13 @@ Handle<DeoptimizationOutputData> Factory::NewDeoptimizationOutputData(
}
+Handle<AccessorPair> Factory::NewAccessorPair() {
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->AllocateAccessorPair(),
+ AccessorPair);
+}
+
+
// Symbols are created in the old generation (data space).
Handle<String> Factory::LookupSymbol(Vector<const char> string) {
CALL_HEAP_FUNCTION(isolate(),
@@ -698,7 +715,7 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name,
// Allocate the function
Handle<JSFunction> function = NewFunction(name, the_hole_value());
- // Setup the code pointer in both the shared function info and in
+ // Set up the code pointer in both the shared function info and in
// the function itself.
function->shared()->set_code(*code);
function->set_code(*code);
@@ -729,7 +746,7 @@ Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
// Allocate the function.
Handle<JSFunction> function = NewFunction(name, prototype);
- // Setup the code pointer in both the shared function info and in
+ // Set up the code pointer in both the shared function info and in
// the function itself.
function->shared()->set_code(*code);
function->set_code(*code);
@@ -751,7 +768,10 @@ Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
// property that refers to the function.
SetPrototypeProperty(function, prototype);
// Currently safe because it is only invoked from Genesis.
- SetLocalPropertyNoThrow(prototype, constructor_symbol(), function, DONT_ENUM);
+ CHECK_NOT_EMPTY_HANDLE(isolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ prototype, constructor_symbol(),
+ function, DONT_ENUM));
return function;
}
@@ -1061,13 +1081,23 @@ Handle<String> Factory::Uint32ToString(uint32_t value) {
}
-Handle<NumberDictionary> Factory::DictionaryAtNumberPut(
- Handle<NumberDictionary> dictionary,
+Handle<SeededNumberDictionary> Factory::DictionaryAtNumberPut(
+ Handle<SeededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value) {
+ CALL_HEAP_FUNCTION(isolate(),
+ dictionary->AtNumberPut(key, *value),
+ SeededNumberDictionary);
+}
+
+
+Handle<UnseededNumberDictionary> Factory::DictionaryAtNumberPut(
+ Handle<UnseededNumberDictionary> dictionary,
uint32_t key,
Handle<Object> value) {
CALL_HEAP_FUNCTION(isolate(),
dictionary->AtNumberPut(key, *value),
- NumberDictionary);
+ UnseededNumberDictionary);
}
diff --git a/deps/v8/src/factory.h b/deps/v8/src/factory.h
index e9a43fd4fc..8725b67ec9 100644
--- a/deps/v8/src/factory.h
+++ b/deps/v8/src/factory.h
@@ -54,7 +54,11 @@ class Factory {
int size,
PretenureFlag pretenure = NOT_TENURED);
- Handle<NumberDictionary> NewNumberDictionary(int at_least_space_for);
+ Handle<SeededNumberDictionary> NewSeededNumberDictionary(
+ int at_least_space_for);
+
+ Handle<UnseededNumberDictionary> NewUnseededNumberDictionary(
+ int at_least_space_for);
Handle<StringDictionary> NewStringDictionary(int at_least_space_for);
@@ -69,6 +73,8 @@ class Factory {
Handle<DeoptimizationOutputData> NewDeoptimizationOutputData(
int deopt_entry_count,
PretenureFlag pretenure);
+ // Allocates a pre-tenured empty AccessorPair.
+ Handle<AccessorPair> NewAccessorPair();
Handle<String> LookupSymbol(Vector<const char> str);
Handle<String> LookupSymbol(Handle<String> str);
@@ -430,8 +436,13 @@ class Factory {
Handle<Object> stack_trace,
Handle<Object> stack_frames);
- Handle<NumberDictionary> DictionaryAtNumberPut(
- Handle<NumberDictionary>,
+ Handle<SeededNumberDictionary> DictionaryAtNumberPut(
+ Handle<SeededNumberDictionary>,
+ uint32_t key,
+ Handle<Object> value);
+
+ Handle<UnseededNumberDictionary> DictionaryAtNumberPut(
+ Handle<UnseededNumberDictionary>,
uint32_t key,
Handle<Object> value);
diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h
index 07060dcb03..9284e1369f 100644
--- a/deps/v8/src/flag-definitions.h
+++ b/deps/v8/src/flag-definitions.h
@@ -349,13 +349,13 @@ DEFINE_bool(trace_exception, false,
"print stack trace when throwing exceptions")
DEFINE_bool(preallocate_message_memory, false,
"preallocate some memory to build stack traces.")
-DEFINE_bool(randomize_string_hashes,
+DEFINE_bool(randomize_hashes,
true,
- "randomize string hashes to avoid predictable hash collisions "
+ "randomize hashes to avoid predictable hash collisions "
"(with snapshots this option cannot override the baked-in seed)")
-DEFINE_int(string_hash_seed,
+DEFINE_int(hash_seed,
0,
- "Fixed seed to use to string hashing (0 means random)"
+ "Fixed seed to use to hash property keys (0 means random)"
"(with snapshots this option cannot override the baked-in seed)")
// v8.cc
diff --git a/deps/v8/src/frames.cc b/deps/v8/src/frames.cc
index e3ed2de4e3..3a46e0869f 100644
--- a/deps/v8/src/frames.cc
+++ b/deps/v8/src/frames.cc
@@ -485,7 +485,7 @@ Code* ExitFrame::unchecked_code() const {
void ExitFrame::ComputeCallerState(State* state) const {
- // Setup the caller state.
+ // Set up the caller state.
state->sp = caller_sp();
state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
state->pc_address
@@ -1303,7 +1303,8 @@ InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
isolate_->counters()->pc_to_code()->Increment();
ASSERT(IsPowerOf2(kInnerPointerToCodeCacheSize));
uint32_t hash = ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer)));
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer)),
+ v8::internal::kZeroHashSeed);
uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
InnerPointerToCodeCacheEntry* entry = cache(index);
if (entry->inner_pointer == inner_pointer) {
diff --git a/deps/v8/src/full-codegen.cc b/deps/v8/src/full-codegen.cc
index 04086d483d..5c7a23d54d 100644
--- a/deps/v8/src/full-codegen.cc
+++ b/deps/v8/src/full-codegen.cc
@@ -1178,7 +1178,7 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
}
ExitFinallyBlock(); // Return to the calling code.
- // Setup try handler.
+ // Set up try handler.
__ bind(&try_entry);
__ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER, stmt->index());
{ TryFinally try_body(this, &finally_entry);
@@ -1284,7 +1284,7 @@ FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit(
bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
- Expression *sub_expr;
+ Expression* sub_expr;
Handle<String> check;
if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
EmitLiteralCompareTypeof(expr, sub_expr, check);
diff --git a/deps/v8/src/gdb-jit.cc b/deps/v8/src/gdb-jit.cc
index b386bed177..4192222f90 100644
--- a/deps/v8/src/gdb-jit.cc
+++ b/deps/v8/src/gdb-jit.cc
@@ -1556,23 +1556,23 @@ class DebugLineSection : public DebugSection {
class UnwindInfoSection : public DebugSection {
public:
- explicit UnwindInfoSection(CodeDescription *desc);
- virtual bool WriteBody(Writer *w);
+ explicit UnwindInfoSection(CodeDescription* desc);
+ virtual bool WriteBody(Writer* w);
- int WriteCIE(Writer *w);
- void WriteFDE(Writer *w, int);
+ int WriteCIE(Writer* w);
+ void WriteFDE(Writer* w, int);
- void WriteFDEStateOnEntry(Writer *w);
- void WriteFDEStateAfterRBPPush(Writer *w);
- void WriteFDEStateAfterRBPSet(Writer *w);
- void WriteFDEStateAfterRBPPop(Writer *w);
+ void WriteFDEStateOnEntry(Writer* w);
+ void WriteFDEStateAfterRBPPush(Writer* w);
+ void WriteFDEStateAfterRBPSet(Writer* w);
+ void WriteFDEStateAfterRBPPop(Writer* w);
- void WriteLength(Writer *w,
+ void WriteLength(Writer* w,
Writer::Slot<uint32_t>* length_slot,
int initial_position);
private:
- CodeDescription *desc_;
+ CodeDescription* desc_;
// DWARF3 Specification, Table 7.23
enum CFIInstructions {
@@ -1623,7 +1623,7 @@ class UnwindInfoSection : public DebugSection {
};
-void UnwindInfoSection::WriteLength(Writer *w,
+void UnwindInfoSection::WriteLength(Writer* w,
Writer::Slot<uint32_t>* length_slot,
int initial_position) {
uint32_t align = (w->position() - initial_position) % kPointerSize;
@@ -1639,7 +1639,7 @@ void UnwindInfoSection::WriteLength(Writer *w,
}
-UnwindInfoSection::UnwindInfoSection(CodeDescription *desc)
+UnwindInfoSection::UnwindInfoSection(CodeDescription* desc)
#ifdef __ELF
: ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1),
#else
@@ -1648,7 +1648,7 @@ UnwindInfoSection::UnwindInfoSection(CodeDescription *desc)
#endif
desc_(desc) { }
-int UnwindInfoSection::WriteCIE(Writer *w) {
+int UnwindInfoSection::WriteCIE(Writer* w) {
Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>();
uint32_t cie_position = w->position();
@@ -1668,7 +1668,7 @@ int UnwindInfoSection::WriteCIE(Writer *w) {
}
-void UnwindInfoSection::WriteFDE(Writer *w, int cie_position) {
+void UnwindInfoSection::WriteFDE(Writer* w, int cie_position) {
// The only FDE for this function. The CFA is the current RBP.
Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>();
int fde_position = w->position();
@@ -1686,7 +1686,7 @@ void UnwindInfoSection::WriteFDE(Writer *w, int cie_position) {
}
-void UnwindInfoSection::WriteFDEStateOnEntry(Writer *w) {
+void UnwindInfoSection::WriteFDEStateOnEntry(Writer* w) {
// The first state, just after the control has been transferred to the the
// function.
@@ -1713,7 +1713,7 @@ void UnwindInfoSection::WriteFDEStateOnEntry(Writer *w) {
}
-void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer *w) {
+void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer* w) {
// The second state, just after RBP has been pushed.
// RBP / CFA for this function is now the current RSP, so just set the
@@ -1734,7 +1734,7 @@ void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer *w) {
}
-void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer *w) {
+void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer* w) {
// The third state, after the RBP has been set.
// The CFA can now directly be set to RBP.
@@ -1749,7 +1749,7 @@ void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer *w) {
}
-void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer *w) {
+void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer* w) {
// The fourth (final) state. The RBP has been popped (just before issuing a
// return).
@@ -1769,7 +1769,7 @@ void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer *w) {
}
-bool UnwindInfoSection::WriteBody(Writer *w) {
+bool UnwindInfoSection::WriteBody(Writer* w) {
uint32_t cie_position = WriteCIE(w);
WriteFDE(w, cie_position);
return true;
@@ -1810,8 +1810,8 @@ extern "C" {
struct JITDescriptor {
uint32_t version_;
uint32_t action_flag_;
- JITCodeEntry *relevant_entry_;
- JITCodeEntry *first_entry_;
+ JITCodeEntry* relevant_entry_;
+ JITCodeEntry* first_entry_;
};
// GDB will place breakpoint into this function.
@@ -1998,7 +1998,7 @@ void GDBJITInterface::AddCode(Handle<String> name,
}
}
-static void AddUnwindInfo(CodeDescription *desc) {
+static void AddUnwindInfo(CodeDescription* desc) {
#ifdef V8_TARGET_ARCH_X64
if (desc->tag() == GDBJITInterface::FUNCTION) {
// To avoid propagating unwinding information through
diff --git a/deps/v8/src/handles.cc b/deps/v8/src/handles.cc
index 2ff797d077..34eaddbbd7 100644
--- a/deps/v8/src/handles.cc
+++ b/deps/v8/src/handles.cc
@@ -208,42 +208,6 @@ void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared,
}
-void NormalizeProperties(Handle<JSObject> object,
- PropertyNormalizationMode mode,
- int expected_additional_properties) {
- CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
- object->NormalizeProperties(
- mode,
- expected_additional_properties));
-}
-
-
-Handle<NumberDictionary> NormalizeElements(Handle<JSObject> object) {
- CALL_HEAP_FUNCTION(object->GetIsolate(),
- object->NormalizeElements(),
- NumberDictionary);
-}
-
-
-void TransformToFastProperties(Handle<JSObject> object,
- int unused_property_fields) {
- CALL_HEAP_FUNCTION_VOID(
- object->GetIsolate(),
- object->TransformToFastProperties(unused_property_fields));
-}
-
-
-Handle<NumberDictionary> NumberDictionarySet(
- Handle<NumberDictionary> dictionary,
- uint32_t index,
- Handle<Object> value,
- PropertyDetails details) {
- CALL_HEAP_FUNCTION(dictionary->GetIsolate(),
- dictionary->Set(index, *value, details),
- NumberDictionary);
-}
-
-
void FlattenString(Handle<String> string) {
CALL_HEAP_FUNCTION_VOID(string->GetIsolate(), string->TryFlatten());
}
@@ -265,17 +229,6 @@ Handle<Object> SetPrototype(Handle<JSFunction> function,
}
-Handle<Object> SetProperty(Handle<JSReceiver> object,
- Handle<String> key,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictModeFlag strict_mode) {
- CALL_HEAP_FUNCTION(object->GetIsolate(),
- object->SetProperty(*key, *value, attributes, strict_mode),
- Object);
-}
-
-
Handle<Object> SetProperty(Handle<Object> object,
Handle<Object> key,
Handle<Object> value,
@@ -303,16 +256,6 @@ Handle<Object> ForceSetProperty(Handle<JSObject> object,
}
-Handle<Object> SetNormalizedProperty(Handle<JSObject> object,
- Handle<String> key,
- Handle<Object> value,
- PropertyDetails details) {
- CALL_HEAP_FUNCTION(object->GetIsolate(),
- object->SetNormalizedProperty(*key, *value, details),
- Object);
-}
-
-
Handle<Object> ForceDeleteProperty(Handle<JSObject> object,
Handle<Object> key) {
Isolate* isolate = object->GetIsolate();
@@ -322,30 +265,6 @@ Handle<Object> ForceDeleteProperty(Handle<JSObject> object,
}
-Handle<Object> SetLocalPropertyIgnoreAttributes(
- Handle<JSObject> object,
- Handle<String> key,
- Handle<Object> value,
- PropertyAttributes attributes) {
- CALL_HEAP_FUNCTION(
- object->GetIsolate(),
- object->SetLocalPropertyIgnoreAttributes(*key, *value, attributes),
- Object);
-}
-
-
-void SetLocalPropertyNoThrow(Handle<JSObject> object,
- Handle<String> key,
- Handle<Object> value,
- PropertyAttributes attributes) {
- Isolate* isolate = object->GetIsolate();
- ASSERT(!isolate->has_pending_exception());
- CHECK(!SetLocalPropertyIgnoreAttributes(
- object, key, value, attributes).is_null());
- CHECK(!isolate->has_pending_exception());
-}
-
-
Handle<Object> SetPropertyWithInterceptor(Handle<JSObject> object,
Handle<String> key,
Handle<Object> value,
@@ -389,12 +308,6 @@ Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
}
-Handle<Object> GetPrototype(Handle<Object> obj) {
- Handle<Object> result(obj->GetPrototype());
- return result;
-}
-
-
Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value) {
const bool skip_hidden_prototypes = false;
CALL_HEAP_FUNCTION(obj->GetIsolate(),
@@ -402,44 +315,6 @@ Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value) {
}
-Handle<Object> PreventExtensions(Handle<JSObject> object) {
- CALL_HEAP_FUNCTION(object->GetIsolate(), object->PreventExtensions(), Object);
-}
-
-
-Handle<Object> SetHiddenProperty(Handle<JSObject> obj,
- Handle<String> key,
- Handle<Object> value) {
- CALL_HEAP_FUNCTION(obj->GetIsolate(),
- obj->SetHiddenProperty(*key, *value),
- Object);
-}
-
-
-int GetIdentityHash(Handle<JSReceiver> obj) {
- CALL_AND_RETRY(obj->GetIsolate(),
- obj->GetIdentityHash(ALLOW_CREATION),
- return Smi::cast(__object__)->value(),
- return 0);
-}
-
-
-Handle<Object> DeleteElement(Handle<JSObject> obj,
- uint32_t index) {
- CALL_HEAP_FUNCTION(obj->GetIsolate(),
- obj->DeleteElement(index, JSObject::NORMAL_DELETION),
- Object);
-}
-
-
-Handle<Object> DeleteProperty(Handle<JSObject> obj,
- Handle<String> prop) {
- CALL_HEAP_FUNCTION(obj->GetIsolate(),
- obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION),
- Object);
-}
-
-
Handle<Object> LookupSingleCharacterStringFromCode(uint32_t index) {
Isolate* isolate = Isolate::Current();
CALL_HEAP_FUNCTION(
@@ -457,43 +332,6 @@ Handle<String> SubString(Handle<String> str,
}
-Handle<Object> SetElement(Handle<JSObject> object,
- uint32_t index,
- Handle<Object> value,
- StrictModeFlag strict_mode) {
- if (object->HasExternalArrayElements()) {
- if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) {
- bool has_exception;
- Handle<Object> number = Execution::ToNumber(value, &has_exception);
- if (has_exception) return Handle<Object>();
- value = number;
- }
- }
- CALL_HEAP_FUNCTION(object->GetIsolate(),
- object->SetElement(index, *value, strict_mode, true),
- Object);
-}
-
-
-Handle<Object> SetOwnElement(Handle<JSObject> object,
- uint32_t index,
- Handle<Object> value,
- StrictModeFlag strict_mode) {
- ASSERT(!object->HasExternalArrayElements());
- CALL_HEAP_FUNCTION(object->GetIsolate(),
- object->SetElement(index, *value, strict_mode, false),
- Object);
-}
-
-
-Handle<Object> TransitionElementsKind(Handle<JSObject> object,
- ElementsKind to_kind) {
- CALL_HEAP_FUNCTION(object->GetIsolate(),
- object->TransitionElementsKind(to_kind),
- Object);
-}
-
-
Handle<JSObject> Copy(Handle<JSObject> obj) {
Isolate* isolate = obj->GetIsolate();
CALL_HEAP_FUNCTION(isolate,
diff --git a/deps/v8/src/handles.h b/deps/v8/src/handles.h
index cfa65b3786..42089134e4 100644
--- a/deps/v8/src/handles.h
+++ b/deps/v8/src/handles.h
@@ -167,18 +167,6 @@ class HandleScope {
// an object of expected type, or the handle is an error if running out
// of space or encountering an internal error.
-void NormalizeProperties(Handle<JSObject> object,
- PropertyNormalizationMode mode,
- int expected_additional_properties);
-Handle<NumberDictionary> NormalizeElements(Handle<JSObject> object);
-void TransformToFastProperties(Handle<JSObject> object,
- int unused_property_fields);
-MUST_USE_RESULT Handle<NumberDictionary> NumberDictionarySet(
- Handle<NumberDictionary> dictionary,
- uint32_t index,
- Handle<Object> value,
- PropertyDetails details);
-
// Flattens a string.
void FlattenString(Handle<String> str);
@@ -186,12 +174,6 @@ void FlattenString(Handle<String> str);
// string.
Handle<String> FlattenGetString(Handle<String> str);
-Handle<Object> SetProperty(Handle<JSReceiver> object,
- Handle<String> key,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictModeFlag strict_mode);
-
Handle<Object> SetProperty(Handle<Object> object,
Handle<Object> key,
Handle<Object> value,
@@ -203,40 +185,9 @@ Handle<Object> ForceSetProperty(Handle<JSObject> object,
Handle<Object> value,
PropertyAttributes attributes);
-Handle<Object> SetNormalizedProperty(Handle<JSObject> object,
- Handle<String> key,
- Handle<Object> value,
- PropertyDetails details);
-
Handle<Object> ForceDeleteProperty(Handle<JSObject> object,
Handle<Object> key);
-Handle<Object> SetLocalPropertyIgnoreAttributes(
- Handle<JSObject> object,
- Handle<String> key,
- Handle<Object> value,
- PropertyAttributes attributes);
-
-// Used to set local properties on the object we totally control
-// and which therefore has no accessors and alikes.
-void SetLocalPropertyNoThrow(Handle<JSObject> object,
- Handle<String> key,
- Handle<Object> value,
- PropertyAttributes attributes = NONE);
-
-MUST_USE_RESULT Handle<Object> SetElement(Handle<JSObject> object,
- uint32_t index,
- Handle<Object> value,
- StrictModeFlag strict_mode);
-
-Handle<Object> SetOwnElement(Handle<JSObject> object,
- uint32_t index,
- Handle<Object> value,
- StrictModeFlag strict_mode);
-
-Handle<Object> TransitionElementsKind(Handle<JSObject> object,
- ElementsKind to_kind);
-
Handle<Object> GetProperty(Handle<JSReceiver> obj,
const char* name);
@@ -248,21 +199,8 @@ Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
Handle<String> name,
PropertyAttributes* attributes);
-Handle<Object> GetPrototype(Handle<Object> obj);
-
Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value);
-// Sets a hidden property on an object. Returns obj on success, undefined
-// if trying to set the property on a detached proxy.
-Handle<Object> SetHiddenProperty(Handle<JSObject> obj,
- Handle<String> key,
- Handle<Object> value);
-
-int GetIdentityHash(Handle<JSReceiver> obj);
-
-Handle<Object> DeleteElement(Handle<JSObject> obj, uint32_t index);
-Handle<Object> DeleteProperty(Handle<JSObject> obj, Handle<String> prop);
-
Handle<Object> LookupSingleCharacterStringFromCode(uint32_t index);
Handle<JSObject> Copy(Handle<JSObject> obj);
@@ -316,7 +254,6 @@ Handle<String> SubString(Handle<String> str,
int end,
PretenureFlag pretenure = NOT_TENURED);
-
// Sets the expected number of properties for the function's instances.
void SetExpectedNofProperties(Handle<JSFunction> func, int nof);
@@ -335,8 +272,6 @@ Handle<JSGlobalProxy> ReinitializeJSGlobalProxy(
Handle<Object> SetPrototype(Handle<JSFunction> function,
Handle<Object> prototype);
-Handle<Object> PreventExtensions(Handle<JSObject> object);
-
Handle<ObjectHashSet> ObjectHashSetAdd(Handle<ObjectHashSet> table,
Handle<Object> key);
diff --git a/deps/v8/src/heap-inl.h b/deps/v8/src/heap-inl.h
index ef6e58ed0b..4d98fbad10 100644
--- a/deps/v8/src/heap-inl.h
+++ b/deps/v8/src/heap-inl.h
@@ -463,7 +463,7 @@ MaybeObject* Heap::PrepareForCompare(String* str) {
int Heap::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
- ASSERT(HasBeenSetup());
+ ASSERT(HasBeenSetUp());
int amount = amount_of_external_allocated_memory_ + change_in_bytes;
if (change_in_bytes >= 0) {
// Avoid overflow.
diff --git a/deps/v8/src/heap-profiler.cc b/deps/v8/src/heap-profiler.cc
index 46c63c27c8..8be6f27685 100644
--- a/deps/v8/src/heap-profiler.cc
+++ b/deps/v8/src/heap-profiler.cc
@@ -51,7 +51,7 @@ void HeapProfiler::ResetSnapshots() {
}
-void HeapProfiler::Setup() {
+void HeapProfiler::SetUp() {
Isolate* isolate = Isolate::Current();
if (isolate->heap_profiler() == NULL) {
isolate->set_heap_profiler(new HeapProfiler());
diff --git a/deps/v8/src/heap-profiler.h b/deps/v8/src/heap-profiler.h
index b1bc91c307..ef5c4f4b4a 100644
--- a/deps/v8/src/heap-profiler.h
+++ b/deps/v8/src/heap-profiler.h
@@ -48,7 +48,7 @@ class HeapSnapshotsCollection;
// to generate .hp files for use by the GHC/Valgrind tool hp2ps.
class HeapProfiler {
public:
- static void Setup();
+ static void SetUp();
static void TearDown();
static HeapSnapshot* TakeSnapshot(const char* name,
diff --git a/deps/v8/src/heap.cc b/deps/v8/src/heap.cc
index 31cd889cbe..3c871e2706 100644
--- a/deps/v8/src/heap.cc
+++ b/deps/v8/src/heap.cc
@@ -176,7 +176,7 @@ Heap::Heap()
intptr_t Heap::Capacity() {
- if (!HasBeenSetup()) return 0;
+ if (!HasBeenSetUp()) return 0;
return new_space_.Capacity() +
old_pointer_space_->Capacity() +
@@ -188,7 +188,7 @@ intptr_t Heap::Capacity() {
intptr_t Heap::CommittedMemory() {
- if (!HasBeenSetup()) return 0;
+ if (!HasBeenSetUp()) return 0;
return new_space_.CommittedMemory() +
old_pointer_space_->CommittedMemory() +
@@ -200,14 +200,14 @@ intptr_t Heap::CommittedMemory() {
}
intptr_t Heap::CommittedMemoryExecutable() {
- if (!HasBeenSetup()) return 0;
+ if (!HasBeenSetUp()) return 0;
return isolate()->memory_allocator()->SizeExecutable();
}
intptr_t Heap::Available() {
- if (!HasBeenSetup()) return 0;
+ if (!HasBeenSetUp()) return 0;
return new_space_.Available() +
old_pointer_space_->Available() +
@@ -218,7 +218,7 @@ intptr_t Heap::Available() {
}
-bool Heap::HasBeenSetup() {
+bool Heap::HasBeenSetUp() {
return old_pointer_space_ != NULL &&
old_data_space_ != NULL &&
code_space_ != NULL &&
@@ -1354,6 +1354,28 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
}
+void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
+ AssertNoAllocation no_allocation;
+
+ class VisitorAdapter : public ObjectVisitor {
+ public:
+ explicit VisitorAdapter(v8::ExternalResourceVisitor* visitor)
+ : visitor_(visitor) {}
+ virtual void VisitPointers(Object** start, Object** end) {
+ for (Object** p = start; p < end; p++) {
+ if ((*p)->IsExternalString()) {
+ visitor_->VisitExternalString(Utils::ToLocal(
+ Handle<String>(String::cast(*p))));
+ }
+ }
+ }
+ private:
+ v8::ExternalResourceVisitor* visitor_;
+ } visitor_adapter(visitor);
+ external_string_table_.Iterate(&visitor_adapter);
+}
+
+
class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> {
public:
static inline void VisitPointer(Heap* heap, Object** p) {
@@ -1869,6 +1891,19 @@ MaybeObject* Heap::AllocatePolymorphicCodeCache() {
}
+MaybeObject* Heap::AllocateAccessorPair() {
+ Object* result;
+ { MaybeObject* maybe_result = AllocateStruct(ACCESSOR_PAIR_TYPE);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ AccessorPair* accessors = AccessorPair::cast(result);
+ // Later we will have to distinguish between undefined and the hole...
+ // accessors->set_getter(the_hole_value(), SKIP_WRITE_BARRIER);
+ // accessors->set_setter(the_hole_value(), SKIP_WRITE_BARRIER);
+ return accessors;
+}
+
+
const Heap::StringTypeTable Heap::string_type_table[] = {
#define STRING_TYPE_ELEMENT(type, size, name, camel_name) \
{type, size, k##camel_name##MapRootIndex},
@@ -2428,18 +2463,18 @@ bool Heap::CreateInitialObjects() {
// Allocate the code_stubs dictionary. The initial size is set to avoid
// expanding the dictionary during bootstrapping.
- { MaybeObject* maybe_obj = NumberDictionary::Allocate(128);
+ { MaybeObject* maybe_obj = UnseededNumberDictionary::Allocate(128);
if (!maybe_obj->ToObject(&obj)) return false;
}
- set_code_stubs(NumberDictionary::cast(obj));
+ set_code_stubs(UnseededNumberDictionary::cast(obj));
// Allocate the non_monomorphic_cache used in stub-cache.cc. The initial size
// is set to avoid expanding the dictionary during bootstrapping.
- { MaybeObject* maybe_obj = NumberDictionary::Allocate(64);
+ { MaybeObject* maybe_obj = UnseededNumberDictionary::Allocate(64);
if (!maybe_obj->ToObject(&obj)) return false;
}
- set_non_monomorphic_cache(NumberDictionary::cast(obj));
+ set_non_monomorphic_cache(UnseededNumberDictionary::cast(obj));
{ MaybeObject* maybe_obj = AllocatePolymorphicCodeCache();
if (!maybe_obj->ToObject(&obj)) return false;
@@ -3794,7 +3829,7 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
}
Map* new_map = Map::cast(obj);
- // Setup the global object as a normalized object.
+ // Set up the global object as a normalized object.
global->set_map(new_map);
global->map()->clear_instance_descriptors();
global->set_properties(dictionary);
@@ -4727,7 +4762,7 @@ bool Heap::IdleGlobalGC() {
#ifdef DEBUG
void Heap::Print() {
- if (!HasBeenSetup()) return;
+ if (!HasBeenSetUp()) return;
isolate()->PrintStack();
AllSpaces spaces;
for (Space* space = spaces.next(); space != NULL; space = spaces.next())
@@ -4792,7 +4827,7 @@ bool Heap::Contains(HeapObject* value) {
bool Heap::Contains(Address addr) {
if (OS::IsOutsideAllocatedSpace(addr)) return false;
- return HasBeenSetup() &&
+ return HasBeenSetUp() &&
(new_space_.ToSpaceContains(addr) ||
old_pointer_space_->Contains(addr) ||
old_data_space_->Contains(addr) ||
@@ -4810,7 +4845,7 @@ bool Heap::InSpace(HeapObject* value, AllocationSpace space) {
bool Heap::InSpace(Address addr, AllocationSpace space) {
if (OS::IsOutsideAllocatedSpace(addr)) return false;
- if (!HasBeenSetup()) return false;
+ if (!HasBeenSetUp()) return false;
switch (space) {
case NEW_SPACE:
@@ -4835,7 +4870,7 @@ bool Heap::InSpace(Address addr, AllocationSpace space) {
#ifdef DEBUG
void Heap::Verify() {
- ASSERT(HasBeenSetup());
+ ASSERT(HasBeenSetUp());
store_buffer()->Verify();
@@ -5262,7 +5297,7 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
bool Heap::ConfigureHeap(int max_semispace_size,
intptr_t max_old_gen_size,
intptr_t max_executable_size) {
- if (HasBeenSetup()) return false;
+ if (HasBeenSetUp()) return false;
if (max_semispace_size > 0) {
if (max_semispace_size < Page::kPageSize) {
@@ -5551,7 +5586,7 @@ class HeapDebugUtils {
#endif
-bool Heap::Setup(bool create_heap_objects) {
+bool Heap::SetUp(bool create_heap_objects) {
#ifdef DEBUG
allocation_timeout_ = FLAG_gc_interval;
debug_utils_ = new HeapDebugUtils(this);
@@ -5581,12 +5616,12 @@ bool Heap::Setup(bool create_heap_objects) {
MarkMapPointersAsEncoded(false);
- // Setup memory allocator.
- if (!isolate_->memory_allocator()->Setup(MaxReserved(), MaxExecutableSize()))
+ // Set up memory allocator.
+ if (!isolate_->memory_allocator()->SetUp(MaxReserved(), MaxExecutableSize()))
return false;
- // Setup new space.
- if (!new_space_.Setup(reserved_semispace_size_, max_semispace_size_)) {
+ // Set up new space.
+ if (!new_space_.SetUp(reserved_semispace_size_, max_semispace_size_)) {
return false;
}
@@ -5597,7 +5632,7 @@ bool Heap::Setup(bool create_heap_objects) {
OLD_POINTER_SPACE,
NOT_EXECUTABLE);
if (old_pointer_space_ == NULL) return false;
- if (!old_pointer_space_->Setup()) return false;
+ if (!old_pointer_space_->SetUp()) return false;
// Initialize old data space.
old_data_space_ =
@@ -5606,14 +5641,14 @@ bool Heap::Setup(bool create_heap_objects) {
OLD_DATA_SPACE,
NOT_EXECUTABLE);
if (old_data_space_ == NULL) return false;
- if (!old_data_space_->Setup()) return false;
+ if (!old_data_space_->SetUp()) return false;
// Initialize the code space, set its maximum capacity to the old
// generation size. It needs executable memory.
// On 64-bit platform(s), we put all code objects in a 2 GB range of
// virtual address space, so that they can call each other with near calls.
if (code_range_size_ > 0) {
- if (!isolate_->code_range()->Setup(code_range_size_)) {
+ if (!isolate_->code_range()->SetUp(code_range_size_)) {
return false;
}
}
@@ -5621,7 +5656,7 @@ bool Heap::Setup(bool create_heap_objects) {
code_space_ =
new OldSpace(this, max_old_generation_size_, CODE_SPACE, EXECUTABLE);
if (code_space_ == NULL) return false;
- if (!code_space_->Setup()) return false;
+ if (!code_space_->SetUp()) return false;
// Initialize map space.
map_space_ = new MapSpace(this,
@@ -5629,28 +5664,28 @@ bool Heap::Setup(bool create_heap_objects) {
FLAG_max_map_space_pages,
MAP_SPACE);
if (map_space_ == NULL) return false;
- if (!map_space_->Setup()) return false;
+ if (!map_space_->SetUp()) return false;
// Initialize global property cell space.
cell_space_ = new CellSpace(this, max_old_generation_size_, CELL_SPACE);
if (cell_space_ == NULL) return false;
- if (!cell_space_->Setup()) return false;
+ if (!cell_space_->SetUp()) return false;
// The large object code space may contain code or data. We set the memory
// to be non-executable here for safety, but this means we need to enable it
// explicitly when allocating large code objects.
lo_space_ = new LargeObjectSpace(this, max_old_generation_size_, LO_SPACE);
if (lo_space_ == NULL) return false;
- if (!lo_space_->Setup()) return false;
+ if (!lo_space_->SetUp()) return false;
- // Setup the seed that is used to randomize the string hash function.
- ASSERT(string_hash_seed() == 0);
- if (FLAG_randomize_string_hashes) {
- if (FLAG_string_hash_seed == 0) {
- set_string_hash_seed(
+ // Set up the seed that is used to randomize the string hash function.
+ ASSERT(hash_seed() == 0);
+ if (FLAG_randomize_hashes) {
+ if (FLAG_hash_seed == 0) {
+ set_hash_seed(
Smi::FromInt(V8::RandomPrivate(isolate()) & 0x3fffffff));
} else {
- set_string_hash_seed(Smi::FromInt(FLAG_string_hash_seed));
+ set_hash_seed(Smi::FromInt(FLAG_hash_seed));
}
}
@@ -5668,7 +5703,7 @@ bool Heap::Setup(bool create_heap_objects) {
LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
LOG(isolate_, IntPtrTEvent("heap-available", Available()));
- store_buffer()->Setup();
+ store_buffer()->SetUp();
return true;
}
diff --git a/deps/v8/src/heap.h b/deps/v8/src/heap.h
index 2d993bbc2b..a1a53db4a3 100644
--- a/deps/v8/src/heap.h
+++ b/deps/v8/src/heap.h
@@ -96,7 +96,7 @@ inline Heap* _inline_get_heap_();
V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \
V(FixedArray, string_split_cache, StringSplitCache) \
V(Object, termination_exception, TerminationException) \
- V(Smi, string_hash_seed, StringHashSeed) \
+ V(Smi, hash_seed, HashSeed) \
V(Map, string_map, StringMap) \
V(Map, symbol_map, SymbolMap) \
V(Map, cons_string_map, ConsStringMap) \
@@ -146,8 +146,8 @@ inline Heap* _inline_get_heap_();
V(Map, neander_map, NeanderMap) \
V(JSObject, message_listeners, MessageListeners) \
V(Foreign, prototype_accessors, PrototypeAccessors) \
- V(NumberDictionary, code_stubs, CodeStubs) \
- V(NumberDictionary, non_monomorphic_cache, NonMonomorphicCache) \
+ V(UnseededNumberDictionary, code_stubs, CodeStubs) \
+ V(UnseededNumberDictionary, non_monomorphic_cache, NonMonomorphicCache) \
V(PolymorphicCodeCache, polymorphic_code_cache, PolymorphicCodeCache) \
V(Code, js_entry_code, JsEntryCode) \
V(Code, js_construct_entry_code, JsConstructEntryCode) \
@@ -434,7 +434,7 @@ class ExternalStringTable {
class Heap {
public:
// Configure heap size before setup. Return false if the heap has been
- // setup already.
+ // set up already.
bool ConfigureHeap(int max_semispace_size,
intptr_t max_old_gen_size,
intptr_t max_executable_size);
@@ -443,7 +443,7 @@ class Heap {
// Initializes the global object heap. If create_heap_objects is true,
// also creates the basic non-mutable objects.
// Returns whether it succeeded.
- bool Setup(bool create_heap_objects);
+ bool SetUp(bool create_heap_objects);
// Destroys all memory allocated by the heap.
void TearDown();
@@ -453,8 +453,8 @@ class Heap {
// jslimit_/real_jslimit_ variable in the StackGuard.
void SetStackLimits();
- // Returns whether Setup has been called.
- bool HasBeenSetup();
+ // Returns whether SetUp has been called.
+ bool HasBeenSetUp();
// Returns the maximum amount of memory reserved for the heap. For
// the young generation, we reserve 4 times the amount needed for a
@@ -615,6 +615,9 @@ class Heap {
// Allocates an empty PolymorphicCodeCache.
MUST_USE_RESULT MaybeObject* AllocatePolymorphicCodeCache();
+ // Allocates a pre-tenured empty AccessorPair.
+ MUST_USE_RESULT MaybeObject* AllocateAccessorPair();
+
// Clear the Instanceof cache (used when a prototype changes).
inline void ClearInstanceofCache();
@@ -1136,7 +1139,7 @@ class Heap {
inline AllocationSpace TargetSpaceId(InstanceType type);
// Sets the stub_cache_ (only used when expanding the dictionary).
- void public_set_code_stubs(NumberDictionary* value) {
+ void public_set_code_stubs(UnseededNumberDictionary* value) {
roots_[kCodeStubsRootIndex] = value;
}
@@ -1148,7 +1151,7 @@ class Heap {
}
// Sets the non_monomorphic_cache_ (only used when expanding the dictionary).
- void public_set_non_monomorphic_cache(NumberDictionary* value) {
+ void public_set_non_monomorphic_cache(UnseededNumberDictionary* value) {
roots_[kNonMonomorphicCacheRootIndex] = value;
}
@@ -1409,6 +1412,8 @@ class Heap {
void ProcessWeakReferences(WeakObjectRetainer* retainer);
+ void VisitExternalResources(v8::ExternalResourceVisitor* visitor);
+
// Helper function that governs the promotion policy from new space to
// old. If the object's old address lies below the new space's age
// mark or if we've already filled the bottom 1/16th of the to space,
@@ -1506,9 +1511,9 @@ class Heap {
return idle_notification_will_schedule_next_gc_;
}
- uint32_t StringHashSeed() {
- uint32_t seed = static_cast<uint32_t>(string_hash_seed()->value());
- ASSERT(FLAG_randomize_string_hashes || seed == 0);
+ uint32_t HashSeed() {
+ uint32_t seed = static_cast<uint32_t>(hash_seed()->value());
+ ASSERT(FLAG_randomize_hashes || seed == 0);
return seed;
}
@@ -1911,7 +1916,7 @@ class Heap {
PromotionQueue promotion_queue_;
// Flag is set when the heap has been configured. The heap can be repeatedly
- // configured through the API until it is setup.
+ // configured through the API until it is set up.
bool configured_;
ExternalStringTable external_string_table_;
diff --git a/deps/v8/src/hydrogen-instructions.cc b/deps/v8/src/hydrogen-instructions.cc
index 1ff7f16fdf..887e80afc4 100644
--- a/deps/v8/src/hydrogen-instructions.cc
+++ b/deps/v8/src/hydrogen-instructions.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -788,6 +788,29 @@ HValue* HTypeof::Canonicalize() {
}
+HValue* HBitwise::Canonicalize() {
+ if (!representation().IsInteger32()) return this;
+ // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x.
+ int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0;
+ if (left()->IsConstant() &&
+ HConstant::cast(left())->HasInteger32Value() &&
+ HConstant::cast(left())->Integer32Value() == nop_constant) {
+ return right();
+ }
+ if (right()->IsConstant() &&
+ HConstant::cast(right())->HasInteger32Value() &&
+ HConstant::cast(right())->Integer32Value() == nop_constant) {
+ return left();
+ }
+ return this;
+}
+
+
+HValue* HChange::Canonicalize() {
+ return (from().Equals(to())) ? value() : this;
+}
+
+
void HTypeof::PrintDataTo(StringStream* stream) {
value()->PrintNameTo(stream);
}
diff --git a/deps/v8/src/hydrogen-instructions.h b/deps/v8/src/hydrogen-instructions.h
index 1856c80929..5082e4d3ff 100644
--- a/deps/v8/src/hydrogen-instructions.h
+++ b/deps/v8/src/hydrogen-instructions.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -146,6 +146,7 @@ class LChunkBuilder;
V(Parameter) \
V(Power) \
V(PushArgument) \
+ V(Random) \
V(RegExpLiteral) \
V(Return) \
V(Sar) \
@@ -1130,12 +1131,16 @@ class HChange: public HUnaryOperation {
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
virtual HType CalculateInferredType();
+ virtual HValue* Canonicalize();
Representation from() { return value()->representation(); }
Representation to() { return representation(); }
bool deoptimize_on_undefined() const {
return CheckFlag(kDeoptimizeOnUndefined);
}
+ bool deoptimize_on_minus_zero() const {
+ return CheckFlag(kBailoutOnMinusZero);
+ }
virtual Representation RequiredInputRepresentation(int index) {
return from();
}
@@ -1921,8 +1926,11 @@ class HLoadExternalArrayPointer: public HUnaryOperation {
class HCheckMap: public HTemplateInstruction<2> {
public:
- HCheckMap(HValue* value, Handle<Map> map, HValue* typecheck = NULL)
- : map_(map) {
+ HCheckMap(HValue* value, Handle<Map> map,
+ HValue* typecheck = NULL,
+ CompareMapMode mode = REQUIRE_EXACT_MAP)
+ : map_(map),
+ mode_(mode) {
SetOperandAt(0, value);
// If callers don't depend on a typecheck, they can pass in NULL. In that
// case we use a copy of the |value| argument as a dummy value.
@@ -1930,6 +1938,9 @@ class HCheckMap: public HTemplateInstruction<2> {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
SetFlag(kDependsOnMaps);
+ has_element_transitions_ =
+ map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL) != NULL ||
+ map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL) != NULL;
}
virtual Representation RequiredInputRepresentation(int index) {
@@ -1940,17 +1951,24 @@ class HCheckMap: public HTemplateInstruction<2> {
HValue* value() { return OperandAt(0); }
Handle<Map> map() const { return map_; }
+ CompareMapMode mode() const { return mode_; }
DECLARE_CONCRETE_INSTRUCTION(CheckMap)
protected:
virtual bool DataEquals(HValue* other) {
HCheckMap* b = HCheckMap::cast(other);
- return map_.is_identical_to(b->map());
+ // Two CheckMaps instructions are DataEqual if their maps are identical and
+ // they have the same mode. The mode comparison can be ignored if the map
+ // has no elements transitions.
+ return map_.is_identical_to(b->map()) &&
+ (b->mode() == mode() || !has_element_transitions_);
}
private:
+ bool has_element_transitions_;
Handle<Map> map_;
+ CompareMapMode mode_;
};
@@ -2985,6 +3003,23 @@ class HPower: public HTemplateInstruction<2> {
};
+class HRandom: public HTemplateInstruction<1> {
+ public:
+ explicit HRandom(HValue* global_object) {
+ SetOperandAt(0, global_object);
+ set_representation(Representation::Double());
+ }
+
+ HValue* global_object() { return OperandAt(0); }
+
+ virtual Representation RequiredInputRepresentation(int index) {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Random)
+};
+
+
class HAdd: public HArithmeticBinaryOperation {
public:
HAdd(HValue* context, HValue* left, HValue* right)
@@ -3138,6 +3173,8 @@ class HBitwise: public HBitwiseBinaryOperation {
virtual bool IsCommutative() const { return true; }
+ virtual HValue* Canonicalize();
+
static HInstruction* NewHBitwise(Zone* zone,
Token::Value op,
HValue* context,
diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc
index 9230870432..47dcc80536 100644
--- a/deps/v8/src/hydrogen.cc
+++ b/deps/v8/src/hydrogen.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -628,7 +628,11 @@ HGraph::HGraph(CompilationInfo* info)
Handle<Code> HGraph::Compile(CompilationInfo* info) {
int values = GetMaximumValueID();
if (values > LAllocator::max_initial_value_ids()) {
- if (FLAG_trace_bailout) PrintF("Function is too big\n");
+ if (FLAG_trace_bailout) {
+ SmartArrayPointer<char> name(
+ info->shared_info()->DebugName()->ToCString());
+ PrintF("Function @\"%s\" is too big.\n", *name);
+ }
return Handle<Code>::null();
}
@@ -2301,7 +2305,7 @@ HGraph* HGraphBuilder::CreateGraph() {
Bailout("function with illegal redeclaration");
return NULL;
}
- SetupScope(scope);
+ SetUpScope(scope);
// 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
@@ -2465,7 +2469,7 @@ HInstruction* HGraphBuilder::PreProcessCall(HCall<V>* call) {
}
-void HGraphBuilder::SetupScope(Scope* scope) {
+void HGraphBuilder::SetUpScope(Scope* scope) {
HConstant* undefined_constant = new(zone()) HConstant(
isolate()->factory()->undefined_value(), Representation::Tagged());
AddInstruction(undefined_constant);
@@ -3572,7 +3576,8 @@ HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object,
bool smi_and_map_check) {
if (smi_and_map_check) {
AddInstruction(new(zone()) HCheckNonSmi(object));
- AddInstruction(new(zone()) HCheckMap(object, type));
+ AddInstruction(new(zone()) HCheckMap(object, type, NULL,
+ ALLOW_ELEMENT_TRANSITION_MAPS));
}
int index = ComputeStoredFieldIndex(type, name, lookup);
@@ -4117,7 +4122,8 @@ HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
bool smi_and_map_check) {
if (smi_and_map_check) {
AddInstruction(new(zone()) HCheckNonSmi(object));
- AddInstruction(new(zone()) HCheckMap(object, type));
+ AddInstruction(new(zone()) HCheckMap(object, type, NULL,
+ ALLOW_ELEMENT_TRANSITION_MAPS));
}
int index = lookup->GetLocalFieldIndexFromMap(*type);
@@ -4157,7 +4163,8 @@ HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj,
true);
} else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) {
AddInstruction(new(zone()) HCheckNonSmi(obj));
- AddInstruction(new(zone()) HCheckMap(obj, map));
+ AddInstruction(new(zone()) HCheckMap(obj, map, NULL,
+ ALLOW_ELEMENT_TRANSITION_MAPS));
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
return new(zone()) HConstant(function, Representation::Tagged());
} else {
@@ -4652,7 +4659,8 @@ void HGraphBuilder::AddCheckConstantFunction(Call* expr,
// its prototypes.
if (smi_and_map_check) {
AddInstruction(new(zone()) HCheckNonSmi(receiver));
- AddInstruction(new(zone()) HCheckMap(receiver, receiver_map));
+ AddInstruction(new(zone()) HCheckMap(receiver, receiver_map, NULL,
+ ALLOW_ELEMENT_TRANSITION_MAPS));
}
if (!expr->holder().is_null()) {
AddInstruction(new(zone()) HCheckPrototypeMaps(
@@ -5124,6 +5132,69 @@ bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr,
return true;
}
break;
+ case kMathRandom:
+ if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
+ AddCheckConstantFunction(expr, receiver, receiver_map, true);
+ Drop(1);
+ HValue* context = environment()->LookupContext();
+ HGlobalObject* global_object = new(zone()) HGlobalObject(context);
+ AddInstruction(global_object);
+ HRandom* result = new(zone()) HRandom(global_object);
+ ast_context()->ReturnInstruction(result, expr->id());
+ return true;
+ }
+ break;
+ case kMathMax:
+ case kMathMin:
+ if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
+ AddCheckConstantFunction(expr, receiver, receiver_map, true);
+ HValue* right = Pop();
+ HValue* left = Pop();
+ // Do not inline if the return representation is not certain.
+ if (!left->representation().Equals(right->representation())) {
+ Push(left);
+ Push(right);
+ return false;
+ }
+
+ Pop(); // Pop receiver.
+ Token::Value op = (id == kMathMin) ? Token::LT : Token::GT;
+ HCompareIDAndBranch* compare = NULL;
+
+ if (left->representation().IsTagged()) {
+ HChange* left_cvt =
+ new(zone()) HChange(left, Representation::Double(), false, true);
+ left_cvt->SetFlag(HValue::kBailoutOnMinusZero);
+ AddInstruction(left_cvt);
+ HChange* right_cvt =
+ new(zone()) HChange(right, Representation::Double(), false, true);
+ right_cvt->SetFlag(HValue::kBailoutOnMinusZero);
+ AddInstruction(right_cvt);
+ compare = new(zone()) HCompareIDAndBranch(left_cvt, right_cvt, op);
+ compare->SetInputRepresentation(Representation::Double());
+ } else {
+ compare = new(zone()) HCompareIDAndBranch(left, right, op);
+ compare->SetInputRepresentation(left->representation());
+ }
+
+ HBasicBlock* return_left = graph()->CreateBasicBlock();
+ HBasicBlock* return_right = graph()->CreateBasicBlock();
+
+ compare->SetSuccessorAt(0, return_left);
+ compare->SetSuccessorAt(1, return_right);
+ current_block()->Finish(compare);
+
+ set_current_block(return_left);
+ Push(left);
+ set_current_block(return_right);
+ Push(right);
+
+ HBasicBlock* join = CreateJoin(return_left, return_right, expr->id());
+ set_current_block(join);
+ ast_context()->ReturnValue(Pop());
+ return true;
+ }
+ break;
default:
// Not yet supported for inlining.
break;
@@ -6195,9 +6266,11 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
Handle<Map> map = oracle()->GetCompareMap(expr);
if (!map.is_null()) {
AddInstruction(new(zone()) HCheckNonSmi(left));
- AddInstruction(new(zone()) HCheckMap(left, map));
+ AddInstruction(new(zone()) HCheckMap(left, map, NULL,
+ ALLOW_ELEMENT_TRANSITION_MAPS));
AddInstruction(new(zone()) HCheckNonSmi(right));
- AddInstruction(new(zone()) HCheckMap(right, map));
+ AddInstruction(new(zone()) HCheckMap(right, map, NULL,
+ ALLOW_ELEMENT_TRANSITION_MAPS));
HCompareObjectEqAndBranch* result =
new(zone()) HCompareObjectEqAndBranch(left, right);
result->set_position(expr->position());
@@ -6569,7 +6642,11 @@ void HGraphBuilder::GenerateLog(CallRuntime* call) {
// Fast support for Math.random().
void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) {
- return Bailout("inlined runtime function: RandomHeapNumber");
+ HValue* context = environment()->LookupContext();
+ HGlobalObject* global_object = new(zone()) HGlobalObject(context);
+ AddInstruction(global_object);
+ HRandom* result = new(zone()) HRandom(global_object);
+ return ast_context()->ReturnInstruction(result, call->id());
}
diff --git a/deps/v8/src/hydrogen.h b/deps/v8/src/hydrogen.h
index ded1356d18..9705859066 100644
--- a/deps/v8/src/hydrogen.h
+++ b/deps/v8/src/hydrogen.h
@@ -870,7 +870,7 @@ class HGraphBuilder: public AstVisitor {
Representation rep);
static Representation ToRepresentation(TypeInfo info);
- void SetupScope(Scope* scope);
+ void SetUpScope(Scope* scope);
virtual void VisitStatements(ZoneList<Statement*>* statements);
#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
diff --git a/deps/v8/src/ia32/assembler-ia32.cc b/deps/v8/src/ia32/assembler-ia32.cc
index 7a5a191644..bb050b63f9 100644
--- a/deps/v8/src/ia32/assembler-ia32.cc
+++ b/deps/v8/src/ia32/assembler-ia32.cc
@@ -350,7 +350,7 @@ Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
}
#endif
- // Setup buffer pointers.
+ // Set up buffer pointers.
ASSERT(buffer_ != NULL);
pc_ = buffer_;
reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
@@ -377,7 +377,7 @@ void Assembler::GetCode(CodeDesc* desc) {
// Finalize code (at this point overflow() may be true, but the gap ensures
// that we are still not overlapping instructions and relocation info).
ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
- // Setup code descriptor.
+ // Set up code descriptor.
desc->buffer = buffer_;
desc->buffer_size = buffer_size_;
desc->instr_size = pc_offset();
@@ -2457,7 +2457,7 @@ void Assembler::GrowBuffer() {
V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
}
- // Setup new buffer.
+ // Set up new buffer.
desc.buffer = NewArray<byte>(desc.buffer_size);
desc.instr_size = pc_offset();
desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
diff --git a/deps/v8/src/ia32/builtins-ia32.cc b/deps/v8/src/ia32/builtins-ia32.cc
index 55f66f1df8..4666311af6 100644
--- a/deps/v8/src/ia32/builtins-ia32.cc
+++ b/deps/v8/src/ia32/builtins-ia32.cc
@@ -333,7 +333,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
__ push(ebx);
__ push(ebx);
- // Setup pointer to last argument.
+ // Set up pointer to last argument.
__ lea(ebx, Operand(ebp, StandardFrameConstants::kCallerSPOffset));
// Copy arguments and receiver to the expression stack.
diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc
index 9bc024f40d..b654390c2b 100644
--- a/deps/v8/src/ia32/code-stubs-ia32.cc
+++ b/deps/v8/src/ia32/code-stubs-ia32.cc
@@ -128,14 +128,14 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
// Get the function from the stack.
__ mov(ecx, Operand(esp, 1 * kPointerSize));
- // Setup the object header.
+ // Set up the object header.
Factory* factory = masm->isolate()->factory();
__ mov(FieldOperand(eax, HeapObject::kMapOffset),
factory->function_context_map());
__ mov(FieldOperand(eax, Context::kLengthOffset),
Immediate(Smi::FromInt(length)));
- // Setup the fixed slots.
+ // Set up the fixed slots.
__ Set(ebx, Immediate(0)); // Set to NULL.
__ mov(Operand(eax, Context::SlotOffset(Context::CLOSURE_INDEX)), ecx);
__ mov(Operand(eax, Context::SlotOffset(Context::PREVIOUS_INDEX)), esi);
@@ -179,7 +179,7 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
// Get the serialized scope info from the stack.
__ mov(ebx, Operand(esp, 2 * kPointerSize));
- // Setup the object header.
+ // Set up the object header.
Factory* factory = masm->isolate()->factory();
__ mov(FieldOperand(eax, HeapObject::kMapOffset),
factory->block_context_map());
@@ -202,7 +202,7 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ mov(ecx, ContextOperand(ecx, Context::CLOSURE_INDEX));
__ bind(&after_sentinel);
- // Setup the fixed slots.
+ // Set up the fixed slots.
__ mov(ContextOperand(eax, Context::CLOSURE_INDEX), ecx);
__ mov(ContextOperand(eax, Context::PREVIOUS_INDEX), esi);
__ mov(ContextOperand(eax, Context::EXTENSION_INDEX), ebx);
@@ -3379,7 +3379,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
__ mov(FieldOperand(eax, i), edx);
}
- // Setup the callee in-object property.
+ // Set up the callee in-object property.
STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
__ mov(edx, Operand(esp, 4 * kPointerSize));
__ mov(FieldOperand(eax, JSObject::kHeaderSize +
@@ -3392,7 +3392,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
Heap::kArgumentsLengthIndex * kPointerSize),
ecx);
- // Setup the elements pointer in the allocated arguments object.
+ // Set up the elements pointer in the allocated arguments object.
// If we allocated a parameter map, edi will point there, otherwise to the
// backing store.
__ lea(edi, Operand(eax, Heap::kArgumentsObjectSize));
@@ -3571,7 +3571,7 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Get the parameters pointer from the stack.
__ mov(edx, Operand(esp, 2 * kPointerSize));
- // Setup the elements pointer in the allocated arguments object and
+ // Set up the elements pointer in the allocated arguments object and
// initialize the header in the elements fixed array.
__ lea(edi, Operand(eax, Heap::kArgumentsObjectSizeStrict));
__ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
@@ -4950,7 +4950,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
Label invoke, handler_entry, exit;
Label not_outermost_js, not_outermost_js_2;
- // Setup frame.
+ // Set up frame.
__ push(ebp);
__ mov(ebp, esp);
@@ -5081,8 +5081,8 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
static const int kDeltaToCmpImmediate = 2;
static const int kDeltaToMov = 8;
static const int kDeltaToMovImmediate = 9;
- static const int8_t kCmpEdiImmediateByte1 = BitCast<int8_t, uint8_t>(0x81);
- static const int8_t kCmpEdiImmediateByte2 = BitCast<int8_t, uint8_t>(0xff);
+ static const int8_t kCmpEdiOperandByte1 = BitCast<int8_t, uint8_t>(0x3b);
+ static const int8_t kCmpEdiOperandByte2 = BitCast<int8_t, uint8_t>(0x3d);
static const int8_t kMovEaxImmediateByte = BitCast<int8_t, uint8_t>(0xb8);
ExternalReference roots_array_start =
@@ -5147,12 +5147,13 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ mov(scratch, Operand(esp, 0 * kPointerSize));
__ sub(scratch, Operand(esp, 1 * kPointerSize));
if (FLAG_debug_code) {
- __ cmpb(Operand(scratch, 0), kCmpEdiImmediateByte1);
+ __ cmpb(Operand(scratch, 0), kCmpEdiOperandByte1);
__ Assert(equal, "InstanceofStub unexpected call site cache (cmp 1)");
- __ cmpb(Operand(scratch, 1), kCmpEdiImmediateByte2);
+ __ cmpb(Operand(scratch, 1), kCmpEdiOperandByte2);
__ Assert(equal, "InstanceofStub unexpected call site cache (cmp 2)");
}
- __ mov(Operand(scratch, kDeltaToCmpImmediate), map);
+ __ mov(scratch, Operand(scratch, kDeltaToCmpImmediate));
+ __ mov(Operand(scratch, 0), map);
}
// Loop through the prototype chain of the object looking for the function
@@ -6037,7 +6038,7 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
if (Serializer::enabled()) {
ExternalReference roots_array_start =
ExternalReference::roots_array_start(masm->isolate());
- __ mov(scratch, Immediate(Heap::kStringHashSeedRootIndex));
+ __ mov(scratch, Immediate(Heap::kHashSeedRootIndex));
__ mov(scratch, Operand::StaticArray(scratch,
times_pointer_size,
roots_array_start));
@@ -6046,7 +6047,7 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
__ shl(scratch, 10);
__ add(hash, scratch);
} else {
- int32_t seed = masm->isolate()->heap()->StringHashSeed();
+ int32_t seed = masm->isolate()->heap()->HashSeed();
__ lea(scratch, Operand(character, seed));
__ shl(scratch, 10);
__ lea(hash, Operand(scratch, character, times_1, seed));
@@ -6091,14 +6092,12 @@ void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
__ shl(scratch, 15);
__ add(hash, scratch);
- uint32_t kHashShiftCutOffMask = (1 << (32 - String::kHashShift)) - 1;
- __ and_(hash, kHashShiftCutOffMask);
+ __ and_(hash, String::kHashBitMask);
// if (hash == 0) hash = 27;
Label hash_not_zero;
- __ test(hash, hash);
__ j(not_zero, &hash_not_zero, Label::kNear);
- __ mov(hash, Immediate(27));
+ __ mov(hash, Immediate(StringHasher::kZeroHash));
__ bind(&hash_not_zero);
}
diff --git a/deps/v8/src/ia32/cpu-ia32.cc b/deps/v8/src/ia32/cpu-ia32.cc
index 57e66df9e3..9eabb2a969 100644
--- a/deps/v8/src/ia32/cpu-ia32.cc
+++ b/deps/v8/src/ia32/cpu-ia32.cc
@@ -41,7 +41,7 @@
namespace v8 {
namespace internal {
-void CPU::Setup() {
+void CPU::SetUp() {
CpuFeatures::Probe();
}
diff --git a/deps/v8/src/ia32/deoptimizer-ia32.cc b/deps/v8/src/ia32/deoptimizer-ia32.cc
index 98c240079e..292315d10c 100644
--- a/deps/v8/src/ia32/deoptimizer-ia32.cc
+++ b/deps/v8/src/ia32/deoptimizer-ia32.cc
@@ -406,7 +406,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
output_[0] = input_;
output_[0]->SetPc(reinterpret_cast<uint32_t>(from_));
} else {
- // Setup the frame pointer and the context pointer.
+ // Set up the frame pointer and the context pointer.
// All OSR stack frames are dynamically aligned to an 8-byte boundary.
int frame_pointer = input_->GetRegister(ebp.code());
if ((frame_pointer & 0x4) == 0) {
diff --git a/deps/v8/src/ia32/full-codegen-ia32.cc b/deps/v8/src/ia32/full-codegen-ia32.cc
index 6e2391110b..4f3274436a 100644
--- a/deps/v8/src/ia32/full-codegen-ia32.cc
+++ b/deps/v8/src/ia32/full-codegen-ia32.cc
@@ -967,7 +967,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumerationIndexOffset));
__ mov(edx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset));
- // Setup the four remaining stack slots.
+ // Set up the four remaining stack slots.
__ push(eax); // Map.
__ push(edx); // Enumeration cache.
__ mov(eax, FieldOperand(edx, FixedArray::kLengthOffset));
diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.cc b/deps/v8/src/ia32/lithium-codegen-ia32.cc
index 137d62c554..8d412fdb53 100644
--- a/deps/v8/src/ia32/lithium-codegen-ia32.cc
+++ b/deps/v8/src/ia32/lithium-codegen-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -1831,7 +1831,7 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
// Branches to a label or falls through with the answer in the z flag. Trashes
-// the temp registers, but not the input. Only input and temp2 may alias.
+// the temp registers, but not the input.
void LCodeGen::EmitClassOfTest(Label* is_true,
Label* is_false,
Handle<String>class_name,
@@ -1839,7 +1839,8 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
Register temp,
Register temp2) {
ASSERT(!input.is(temp));
- ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register.
+ ASSERT(!input.is(temp2));
+ ASSERT(!temp.is(temp2));
__ JumpIfSmi(input, is_false);
if (class_name->IsEqualTo(CStrVector("Function"))) {
@@ -1899,12 +1900,7 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
Register input = ToRegister(instr->InputAt(0));
Register temp = ToRegister(instr->TempAt(0));
Register temp2 = ToRegister(instr->TempAt(1));
- if (input.is(temp)) {
- // Swap.
- Register swapper = temp;
- temp = temp2;
- temp2 = swapper;
- }
+
Handle<String> class_name = instr->hydrogen()->class_name();
int true_block = chunk_->LookupDestination(instr->true_block_id());
@@ -1979,7 +1975,9 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
Register map = ToRegister(instr->TempAt(0));
__ mov(map, FieldOperand(object, HeapObject::kMapOffset));
__ bind(deferred->map_check()); // Label for calculating code patching.
- __ cmp(map, factory()->the_hole_value()); // Patched to cached map.
+ Handle<JSGlobalPropertyCell> cache_cell =
+ factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
+ __ cmp(map, Operand::Cell(cache_cell)); // Patched to cached map.
__ j(not_equal, &cache_miss, Label::kNear);
__ mov(eax, factory()->the_hole_value()); // Patched to either true or false.
__ jmp(&done);
@@ -3016,6 +3014,29 @@ void LCodeGen::DoPower(LPower* instr) {
}
+void LCodeGen::DoRandom(LRandom* instr) {
+ // Having marked this instruction as a call we can use any
+ // registers.
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+ ASSERT(ToRegister(instr->InputAt(0)).is(eax));
+
+ __ PrepareCallCFunction(1, ebx);
+ __ mov(eax, FieldOperand(eax, GlobalObject::kGlobalContextOffset));
+ __ mov(Operand(esp, 0), eax);
+ __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
+
+ // Convert 32 random bits in eax to 0.(32 random bits) in a double
+ // by computing:
+ // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
+ __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
+ __ movd(xmm2, ebx);
+ __ movd(xmm1, eax);
+ __ cvtss2sd(xmm2, xmm2);
+ __ xorps(xmm1, xmm2);
+ __ subsd(xmm1, xmm2);
+}
+
+
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
ASSERT(instr->value()->Equals(instr->result()));
XMMRegister input_reg = ToDoubleRegister(instr->value());
@@ -3678,8 +3699,10 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
void LCodeGen::EmitNumberUntagD(Register input_reg,
+ Register temp_reg,
XMMRegister result_reg,
bool deoptimize_on_undefined,
+ bool deoptimize_on_minus_zero,
LEnvironment* env) {
Label load_smi, done;
@@ -3708,6 +3731,15 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
}
// Heap number to XMM conversion.
__ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
+ if (deoptimize_on_minus_zero) {
+ XMMRegister xmm_scratch = xmm0;
+ __ xorps(xmm_scratch, xmm_scratch);
+ __ ucomisd(result_reg, xmm_scratch);
+ __ j(not_zero, &done, Label::kNear);
+ __ movmskpd(temp_reg, result_reg);
+ __ test_b(temp_reg, 1);
+ DeoptimizeIf(not_zero, env);
+ }
__ jmp(&done, Label::kNear);
// Smi to XMM conversion
@@ -3830,14 +3862,23 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister());
+ LOperand* temp = instr->TempAt(0);
+ ASSERT(temp == NULL || temp->IsRegister());
LOperand* result = instr->result();
ASSERT(result->IsDoubleRegister());
Register input_reg = ToRegister(input);
XMMRegister result_reg = ToDoubleRegister(result);
- EmitNumberUntagD(input_reg, result_reg,
+ bool deoptimize_on_minus_zero =
+ instr->hydrogen()->deoptimize_on_minus_zero();
+ Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg;
+
+ EmitNumberUntagD(input_reg,
+ temp_reg,
+ result_reg,
instr->hydrogen()->deoptimize_on_undefined(),
+ deoptimize_on_minus_zero,
instr->environment());
}
@@ -4033,13 +4074,23 @@ void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
}
+void LCodeGen::DoCheckMapCommon(Register reg,
+ Handle<Map> map,
+ CompareMapMode mode,
+ LEnvironment* env) {
+ Label success;
+ __ CompareMap(reg, map, &success, mode);
+ DeoptimizeIf(not_equal, env);
+ __ bind(&success);
+}
+
+
void LCodeGen::DoCheckMap(LCheckMap* instr) {
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
- __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
- instr->hydrogen()->map());
- DeoptimizeIf(not_equal, instr->environment());
+ Handle<Map> map = instr->hydrogen()->map();
+ DoCheckMapCommon(reg, map, instr->hydrogen()->mode(), instr->environment());
}
@@ -4102,9 +4153,9 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
// Check prototype maps up to the holder.
while (!current_prototype.is_identical_to(holder)) {
- __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
- Handle<Map>(current_prototype->map()));
- DeoptimizeIf(not_equal, instr->environment());
+ DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()),
+ ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
+
current_prototype =
Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
// Load next prototype object.
@@ -4112,9 +4163,8 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
}
// Check the holder map.
- __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
- Handle<Map>(current_prototype->map()));
- DeoptimizeIf(not_equal, instr->environment());
+ DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()),
+ ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
}
@@ -4139,7 +4189,7 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
DeoptimizeIf(not_equal, instr->environment());
}
- // Setup the parameters to the stub/runtime call.
+ // Set up the parameters to the stub/runtime call.
__ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
__ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
@@ -4247,7 +4297,7 @@ void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) {
Handle<FixedArray> constant_properties =
instr->hydrogen()->constant_properties();
- // Setup the parameters to the stub/runtime call.
+ // Set up the parameters to the stub/runtime call.
__ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
__ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.h b/deps/v8/src/ia32/lithium-codegen-ia32.h
index 375f137d7b..d86d48cd8c 100644
--- a/deps/v8/src/ia32/lithium-codegen-ia32.h
+++ b/deps/v8/src/ia32/lithium-codegen-ia32.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -110,6 +110,9 @@ class LCodeGen BASE_EMBEDDED {
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
Label* map_check);
+ void DoCheckMapCommon(Register reg, Handle<Map> map,
+ CompareMapMode mode, LEnvironment* env);
+
// Parallel move support.
void DoParallelMove(LParallelMove* move);
void DoGap(LGap* instr);
@@ -265,8 +268,10 @@ class LCodeGen BASE_EMBEDDED {
void EmitGoto(int block);
void EmitBranch(int left_block, int right_block, Condition cc);
void EmitNumberUntagD(Register input,
+ Register temp,
XMMRegister result,
bool deoptimize_on_undefined,
+ bool deoptimize_on_minus_zero,
LEnvironment* env);
// Emits optimized code for typeof x == "y". Modifies input register.
@@ -380,7 +385,7 @@ class LDeferredCode: public ZoneObject {
virtual void Generate() = 0;
virtual LInstruction* instr() = 0;
- void SetExit(Label *exit) { external_exit_ = exit; }
+ void SetExit(Label* exit) { external_exit_ = exit; }
Label* entry() { return &entry_; }
Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
int instruction_index() const { return instruction_index_; }
diff --git a/deps/v8/src/ia32/lithium-ia32.cc b/deps/v8/src/ia32/lithium-ia32.cc
index 5cd276f300..8435a3c2a1 100644
--- a/deps/v8/src/ia32/lithium-ia32.cc
+++ b/deps/v8/src/ia32/lithium-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -1047,22 +1047,31 @@ LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
- HValue* v = instr->value();
- if (v->EmitAtUses()) {
- ASSERT(v->IsConstant());
- ASSERT(!v->representation().IsDouble());
- HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
+ HValue* value = instr->value();
+ if (value->EmitAtUses()) {
+ ASSERT(value->IsConstant());
+ ASSERT(!value->representation().IsDouble());
+ HBasicBlock* successor = HConstant::cast(value)->ToBoolean()
? instr->FirstSuccessor()
: instr->SecondSuccessor();
return new(zone()) LGoto(successor->block_id());
}
+
+ // Untagged integers or doubles, smis and booleans don't require a
+ // deoptimization environment nor a temp register.
+ Representation rep = value->representation();
+ HType type = value->type();
+ if (!rep.IsTagged() || type.IsSmi() || type.IsBoolean()) {
+ return new(zone()) LBranch(UseRegister(value), NULL);
+ }
+
ToBooleanStub::Types expected = instr->expected_input_types();
// We need a temporary register when we have to access the map *or* we have
// no type info yet, in which case we handle all cases (including the ones
// involving maps).
bool needs_temp = expected.NeedsMap() || expected.IsEmpty();
LOperand* temp = needs_temp ? TempRegister() : NULL;
- return AssignEnvironment(new(zone()) LBranch(UseRegister(v), temp));
+ return AssignEnvironment(new(zone()) LBranch(UseRegister(value), temp));
}
@@ -1388,7 +1397,11 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
temp = TempRegister();
}
LMulI* mul = new(zone()) LMulI(left, right, temp);
- return AssignEnvironment(DefineSameAsFirst(mul));
+ if (instr->CheckFlag(HValue::kCanOverflow) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ AssignEnvironment(mul);
+ }
+ return DefineSameAsFirst(mul);
} else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::MUL, instr);
} else {
@@ -1456,6 +1469,15 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
}
+LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->global_object()->representation().IsTagged());
+ LOperand* global_object = UseFixed(instr->global_object(), eax);
+ LRandom* result = new(zone()) LRandom(global_object);
+ return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
+}
+
+
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
ASSERT(instr->left()->representation().IsTagged());
ASSERT(instr->right()->representation().IsTagged());
@@ -1588,9 +1610,9 @@ LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
HClassOfTestAndBranch* instr) {
ASSERT(instr->value()->representation().IsTagged());
- return new(zone()) LClassOfTestAndBranch(UseTempRegister(instr->value()),
- TempRegister(),
- TempRegister());
+ return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()),
+ TempRegister(),
+ TempRegister());
}
@@ -1616,7 +1638,7 @@ LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
LOperand* object = UseRegister(instr->value());
LValueOf* result = new(zone()) LValueOf(object, TempRegister());
- return AssignEnvironment(DefineSameAsFirst(result));
+ return DefineSameAsFirst(result);
}
@@ -1660,7 +1682,11 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
if (from.IsTagged()) {
if (to.IsDouble()) {
LOperand* value = UseRegister(instr->value());
- LNumberUntagD* res = new(zone()) LNumberUntagD(value);
+ // Temp register only necessary for minus zero check.
+ LOperand* temp = instr->deoptimize_on_minus_zero()
+ ? TempRegister()
+ : NULL;
+ LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp);
return AssignEnvironment(DefineAsRegister(res));
} else {
ASSERT(to.IsInteger32());
@@ -1956,7 +1982,8 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key);
- return AssignEnvironment(DefineAsRegister(result));
+ if (instr->RequiresHoleCheck()) AssignEnvironment(result);
+ return DefineAsRegister(result);
}
diff --git a/deps/v8/src/ia32/lithium-ia32.h b/deps/v8/src/ia32/lithium-ia32.h
index cc3762d7ab..67bf9376c7 100644
--- a/deps/v8/src/ia32/lithium-ia32.h
+++ b/deps/v8/src/ia32/lithium-ia32.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -135,6 +135,7 @@ class LCodeGen;
V(OuterContext) \
V(Parameter) \
V(Power) \
+ V(Random) \
V(PushArgument) \
V(RegExpLiteral) \
V(Return) \
@@ -1043,6 +1044,17 @@ class LPower: public LTemplateInstruction<1, 2, 0> {
};
+class LRandom: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LRandom(LOperand* global_object) {
+ inputs_[0] = global_object;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Random, "random")
+ DECLARE_HYDROGEN_ACCESSOR(Random)
+};
+
+
class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
public:
LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
@@ -1612,10 +1624,11 @@ class LSmiTag: public LTemplateInstruction<1, 1, 0> {
};
-class LNumberUntagD: public LTemplateInstruction<1, 1, 0> {
+class LNumberUntagD: public LTemplateInstruction<1, 1, 1> {
public:
- explicit LNumberUntagD(LOperand* value) {
+ explicit LNumberUntagD(LOperand* value, LOperand* temp) {
inputs_[0] = value;
+ temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
diff --git a/deps/v8/src/ia32/macro-assembler-ia32.cc b/deps/v8/src/ia32/macro-assembler-ia32.cc
index 3356e81892..43f265cf01 100644
--- a/deps/v8/src/ia32/macro-assembler-ia32.cc
+++ b/deps/v8/src/ia32/macro-assembler-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -487,15 +487,48 @@ void MacroAssembler::StoreNumberToDoubleElements(
}
+void MacroAssembler::CompareMap(Register obj,
+ Handle<Map> map,
+ Label* early_success,
+ CompareMapMode mode) {
+ cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
+ if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
+ Map* transitioned_fast_element_map(
+ map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL));
+ ASSERT(transitioned_fast_element_map == NULL ||
+ map->elements_kind() != FAST_ELEMENTS);
+ if (transitioned_fast_element_map != NULL) {
+ j(equal, early_success, Label::kNear);
+ cmp(FieldOperand(obj, HeapObject::kMapOffset),
+ Handle<Map>(transitioned_fast_element_map));
+ }
+
+ Map* transitioned_double_map(
+ map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL));
+ ASSERT(transitioned_double_map == NULL ||
+ map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
+ if (transitioned_double_map != NULL) {
+ j(equal, early_success, Label::kNear);
+ cmp(FieldOperand(obj, HeapObject::kMapOffset),
+ Handle<Map>(transitioned_double_map));
+ }
+ }
+}
+
+
void MacroAssembler::CheckMap(Register obj,
Handle<Map> map,
Label* fail,
- SmiCheckType smi_check_type) {
+ SmiCheckType smi_check_type,
+ CompareMapMode mode) {
if (smi_check_type == DO_SMI_CHECK) {
JumpIfSmi(obj, fail);
}
- cmp(FieldOperand(obj, HeapObject::kMapOffset), Immediate(map));
+
+ Label success;
+ CompareMap(obj, map, &success, mode);
j(not_equal, fail);
+ bind(&success);
}
@@ -616,7 +649,7 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
void MacroAssembler::EnterExitFramePrologue() {
- // Setup the frame structure on the stack.
+ // Set up the frame structure on the stack.
ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize);
ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize);
ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize);
@@ -668,7 +701,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) {
void MacroAssembler::EnterExitFrame(bool save_doubles) {
EnterExitFramePrologue();
- // Setup argc and argv in callee-saved registers.
+ // Set up argc and argv in callee-saved registers.
int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
mov(edi, eax);
lea(esi, Operand(ebp, eax, times_4, offset));
@@ -959,6 +992,50 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
}
+// Compute the hash code from the untagged key. This must be kept in sync
+// with ComputeIntegerHash in utils.h.
+//
+// Note: r0 will contain hash code
+void MacroAssembler::GetNumberHash(Register r0, Register scratch) {
+ // Xor original key with a seed.
+ if (Serializer::enabled()) {
+ ExternalReference roots_array_start =
+ ExternalReference::roots_array_start(isolate());
+ mov(scratch, Immediate(Heap::kHashSeedRootIndex));
+ mov(scratch,
+ Operand::StaticArray(scratch, times_pointer_size, roots_array_start));
+ SmiUntag(scratch);
+ xor_(r0, scratch);
+ } else {
+ int32_t seed = isolate()->heap()->HashSeed();
+ xor_(r0, Immediate(seed));
+ }
+
+ // hash = ~hash + (hash << 15);
+ mov(scratch, r0);
+ not_(r0);
+ shl(scratch, 15);
+ add(r0, scratch);
+ // hash = hash ^ (hash >> 12);
+ mov(scratch, r0);
+ shr(scratch, 12);
+ xor_(r0, scratch);
+ // hash = hash + (hash << 2);
+ lea(r0, Operand(r0, r0, times_4, 0));
+ // hash = hash ^ (hash >> 4);
+ mov(scratch, r0);
+ shr(scratch, 4);
+ xor_(r0, scratch);
+ // hash = hash * 2057;
+ imul(r0, r0, 2057);
+ // hash = hash ^ (hash >> 16);
+ mov(scratch, r0);
+ shr(scratch, 16);
+ xor_(r0, scratch);
+}
+
+
+
void MacroAssembler::LoadFromNumberDictionary(Label* miss,
Register elements,
Register key,
@@ -984,33 +1061,10 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
Label done;
- // Compute the hash code from the untagged key. This must be kept in sync
- // with ComputeIntegerHash in utils.h.
- //
- // hash = ~hash + (hash << 15);
- mov(r1, r0);
- not_(r0);
- shl(r1, 15);
- add(r0, r1);
- // hash = hash ^ (hash >> 12);
- mov(r1, r0);
- shr(r1, 12);
- xor_(r0, r1);
- // hash = hash + (hash << 2);
- lea(r0, Operand(r0, r0, times_4, 0));
- // hash = hash ^ (hash >> 4);
- mov(r1, r0);
- shr(r1, 4);
- xor_(r0, r1);
- // hash = hash * 2057;
- imul(r0, r0, 2057);
- // hash = hash ^ (hash >> 16);
- mov(r1, r0);
- shr(r1, 16);
- xor_(r0, r1);
+ GetNumberHash(r0, r1);
// Compute capacity mask.
- mov(r1, FieldOperand(elements, NumberDictionary::kCapacityOffset));
+ mov(r1, FieldOperand(elements, SeededNumberDictionary::kCapacityOffset));
shr(r1, kSmiTagSize); // convert smi to int
dec(r1);
@@ -1021,19 +1075,19 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
mov(r2, r0);
// Compute the masked index: (hash + i + i * i) & mask.
if (i > 0) {
- add(r2, Immediate(NumberDictionary::GetProbeOffset(i)));
+ add(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i)));
}
and_(r2, r1);
// Scale the index by multiplying by the entry size.
- ASSERT(NumberDictionary::kEntrySize == 3);
+ ASSERT(SeededNumberDictionary::kEntrySize == 3);
lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3
// Check if the key matches.
cmp(key, FieldOperand(elements,
r2,
times_pointer_size,
- NumberDictionary::kElementsStartOffset));
+ SeededNumberDictionary::kElementsStartOffset));
if (i != (kProbes - 1)) {
j(equal, &done);
} else {
@@ -1044,7 +1098,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
bind(&done);
// Check that the value is a normal propety.
const int kDetailsOffset =
- NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
+ SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
ASSERT_EQ(NORMAL, 0);
test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize));
@@ -1052,7 +1106,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
// Get the value at the masked, scaled index.
const int kValueOffset =
- NumberDictionary::kElementsStartOffset + kPointerSize;
+ SeededNumberDictionary::kElementsStartOffset + kPointerSize;
mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
}
diff --git a/deps/v8/src/ia32/macro-assembler-ia32.h b/deps/v8/src/ia32/macro-assembler-ia32.h
index e6a17417d8..c969a6f71b 100644
--- a/deps/v8/src/ia32/macro-assembler-ia32.h
+++ b/deps/v8/src/ia32/macro-assembler-ia32.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -251,7 +251,7 @@ class MacroAssembler: public Assembler {
// ---------------------------------------------------------------------------
// JavaScript invokes
- // Setup call kind marking in ecx. The method takes ecx as an
+ // Set up call kind marking in ecx. The method takes ecx as an
// explicit first parameter to make the code more readable at the
// call sites.
void SetCallKind(Register dst, CallKind kind);
@@ -356,13 +356,24 @@ class MacroAssembler: public Assembler {
Label* fail,
bool specialize_for_processor);
+ // Compare an object's map with the specified map and its transitioned
+ // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. FLAGS are set with
+ // result of map compare. If multiple map compares are required, the compare
+ // sequences branches to early_success.
+ void CompareMap(Register obj,
+ Handle<Map> map,
+ Label* early_success,
+ CompareMapMode mode = REQUIRE_EXACT_MAP);
+
// Check if the map of an object is equal to a specified map and branch to
// label if not. Skip the smi check if not required (object is known to be a
- // heap object)
+ // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
+ // against maps that are ElementsKind transition maps of the specificed map.
void CheckMap(Register obj,
Handle<Map> map,
Label* fail,
- SmiCheckType smi_check_type);
+ SmiCheckType smi_check_type,
+ CompareMapMode mode = REQUIRE_EXACT_MAP);
// Check if the map of an object is equal to a specified map and branch to a
// specified target if equal. Skip the smi check if not required (object is
@@ -486,6 +497,7 @@ class MacroAssembler: public Assembler {
Register scratch,
Label* miss);
+ void GetNumberHash(Register r0, Register scratch);
void LoadFromNumberDictionary(Label* miss,
Register elements,
diff --git a/deps/v8/src/ia32/stub-cache-ia32.cc b/deps/v8/src/ia32/stub-cache-ia32.cc
index c27a60fd06..0da51c857e 100644
--- a/deps/v8/src/ia32/stub-cache-ia32.cc
+++ b/deps/v8/src/ia32/stub-cache-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -695,13 +695,9 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
Register name_reg,
Register scratch,
Label* miss_label) {
- // Check that the object isn't a smi.
- __ JumpIfSmi(receiver_reg, miss_label);
-
// Check that the map of the object hasn't changed.
- __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset),
- Immediate(Handle<Map>(object->map())));
- __ j(not_equal, miss_label);
+ __ CheckMap(receiver_reg, Handle<Map>(object->map()),
+ miss_label, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
@@ -878,13 +874,10 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
if (in_new_space) {
// Save the map in scratch1 for later.
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
- __ cmp(scratch1, Immediate(current_map));
- } else {
- __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
- Immediate(current_map));
}
- // Branch on the result of the map check.
- __ j(not_equal, miss);
+ __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK,
+ ALLOW_ELEMENT_TRANSITION_MAPS);
+
// Check access rights to the global object. This has to happen after
// the map check so that we know that the object is actually a global
// object.
@@ -916,9 +909,8 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
// Check the holder map.
- __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
- Immediate(Handle<Map>(holder->map())));
- __ j(not_equal, miss);
+ __ CheckMap(reg, Handle<Map>(holder->map()),
+ miss, DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform security check for access to the global object.
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
@@ -2338,7 +2330,7 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
__ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
}
- // Setup the context (function already in edi).
+ // Set up the context (function already in edi).
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
// Jump to the cached code (tail call).
@@ -2403,13 +2395,9 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -----------------------------------
Label miss;
- // Check that the object isn't a smi.
- __ JumpIfSmi(edx, &miss);
-
// Check that the map of the object hasn't changed.
- __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- Immediate(Handle<Map>(object->map())));
- __ j(not_equal, &miss);
+ __ CheckMap(edx, Handle<Map>(object->map()),
+ &miss, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
@@ -2453,13 +2441,9 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
// -----------------------------------
Label miss;
- // Check that the object isn't a smi.
- __ JumpIfSmi(edx, &miss);
-
// Check that the map of the object hasn't changed.
- __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- Immediate(Handle<Map>(receiver->map())));
- __ j(not_equal, &miss);
+ __ CheckMap(edx, Handle<Map>(receiver->map()),
+ &miss, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (receiver->IsJSGlobalProxy()) {
diff --git a/deps/v8/src/ic.cc b/deps/v8/src/ic.cc
index 624ecd7f58..9024605da5 100644
--- a/deps/v8/src/ic.cc
+++ b/deps/v8/src/ic.cc
@@ -1267,7 +1267,8 @@ MaybeObject* StoreIC::Store(State state,
// Check if the given name is an array index.
uint32_t index;
if (name->AsArrayIndex(&index)) {
- Handle<Object> result = SetElement(receiver, index, value, strict_mode);
+ Handle<Object> result =
+ JSObject::SetElement(receiver, index, value, strict_mode);
RETURN_IF_EMPTY_HANDLE(isolate(), result);
return *value;
}
@@ -1644,7 +1645,8 @@ MaybeObject* KeyedStoreIC::Store(State state,
// Check if the given name is an array index.
uint32_t index;
if (name->AsArrayIndex(&index)) {
- Handle<Object> result = SetElement(receiver, index, value, strict_mode);
+ Handle<Object> result =
+ JSObject::SetElement(receiver, index, value, strict_mode);
RETURN_IF_EMPTY_HANDLE(isolate(), result);
return *value;
}
diff --git a/deps/v8/src/incremental-marking.cc b/deps/v8/src/incremental-marking.cc
index 8fca305057..f6d5a5963d 100644
--- a/deps/v8/src/incremental-marking.cc
+++ b/deps/v8/src/incremental-marking.cc
@@ -418,7 +418,7 @@ void IncrementalMarking::ActivateGeneratedStub(Code* stub) {
static void PatchIncrementalMarkingRecordWriteStubs(
Heap* heap, RecordWriteStub::Mode mode) {
- NumberDictionary* stubs = heap->code_stubs();
+ UnseededNumberDictionary* stubs = heap->code_stubs();
int capacity = stubs->Capacity();
for (int i = 0; i < capacity; i++) {
diff --git a/deps/v8/src/incremental-marking.h b/deps/v8/src/incremental-marking.h
index 25def87068..4f8fa6b127 100644
--- a/deps/v8/src/incremental-marking.h
+++ b/deps/v8/src/incremental-marking.h
@@ -56,6 +56,7 @@ class IncrementalMarking {
}
bool should_hurry() { return should_hurry_; }
+ void set_should_hurry(bool val) { should_hurry_ = val; }
inline bool IsStopped() { return state() == STOPPED; }
@@ -219,10 +220,6 @@ class IncrementalMarking {
void UncommitMarkingDeque();
private:
- void set_should_hurry(bool val) {
- should_hurry_ = val;
- }
-
int64_t SpaceLeftInOldSpace();
void ResetStepCounters();
diff --git a/deps/v8/src/inspector.cc b/deps/v8/src/inspector.cc
index 8fb80f1a22..833d338439 100644
--- a/deps/v8/src/inspector.cc
+++ b/deps/v8/src/inspector.cc
@@ -38,11 +38,11 @@ namespace internal {
//============================================================================
// The Inspector.
-void Inspector::DumpObjectType(FILE* out, Object *obj, bool print_more) {
+void Inspector::DumpObjectType(FILE* out, Object* obj, bool print_more) {
// Dump the object pointer.
OS::FPrint(out, "%p:", reinterpret_cast<void*>(obj));
if (obj->IsHeapObject()) {
- HeapObject *hobj = HeapObject::cast(obj);
+ HeapObject* hobj = HeapObject::cast(obj);
OS::FPrint(out, " size %d :", hobj->Size());
}
diff --git a/deps/v8/src/inspector.h b/deps/v8/src/inspector.h
index e328bcdfa5..6962e21f4f 100644
--- a/deps/v8/src/inspector.h
+++ b/deps/v8/src/inspector.h
@@ -41,14 +41,14 @@ namespace internal {
class Inspector {
public:
- static void DumpObjectType(FILE* out, Object *obj, bool print_more);
- static void DumpObjectType(FILE* out, Object *obj) {
+ static void DumpObjectType(FILE* out, Object* obj, bool print_more);
+ static void DumpObjectType(FILE* out, Object* obj) {
DumpObjectType(out, obj, false);
}
- static void DumpObjectType(Object *obj, bool print_more) {
+ static void DumpObjectType(Object* obj, bool print_more) {
DumpObjectType(stdout, obj, print_more);
}
- static void DumpObjectType(Object *obj) {
+ static void DumpObjectType(Object* obj) {
DumpObjectType(stdout, obj, false);
}
};
diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc
index c235a23439..35e9e284f9 100644
--- a/deps/v8/src/isolate.cc
+++ b/deps/v8/src/isolate.cc
@@ -570,7 +570,7 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
frame->Summarize(&frames);
for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
// Create a JSObject to hold the information for the StackFrame.
- Handle<JSObject> stackFrame = factory()->NewJSObject(object_function());
+ Handle<JSObject> stack_frame = factory()->NewJSObject(object_function());
Handle<JSFunction> fun = frames[i].function();
Handle<Script> script(Script::cast(fun->shared()->script()));
@@ -591,16 +591,24 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
// tag.
column_offset += script->column_offset()->value();
}
- SetLocalPropertyNoThrow(stackFrame, column_key,
- Handle<Smi>(Smi::FromInt(column_offset + 1)));
+ CHECK_NOT_EMPTY_HANDLE(
+ this,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, column_key,
+ Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE));
}
- SetLocalPropertyNoThrow(stackFrame, line_key,
- Handle<Smi>(Smi::FromInt(line_number + 1)));
+ CHECK_NOT_EMPTY_HANDLE(
+ this,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, line_key,
+ Handle<Smi>(Smi::FromInt(line_number + 1)), NONE));
}
if (options & StackTrace::kScriptName) {
Handle<Object> script_name(script->name(), this);
- SetLocalPropertyNoThrow(stackFrame, script_key, script_name);
+ CHECK_NOT_EMPTY_HANDLE(this,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, script_key, script_name, NONE));
}
if (options & StackTrace::kScriptNameOrSourceURL) {
@@ -616,8 +624,10 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
if (caught_exception) {
result = factory()->undefined_value();
}
- SetLocalPropertyNoThrow(stackFrame, script_name_or_source_url_key,
- result);
+ CHECK_NOT_EMPTY_HANDLE(this,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, script_name_or_source_url_key,
+ result, NONE));
}
if (options & StackTrace::kFunctionName) {
@@ -625,23 +635,30 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
if (fun_name->ToBoolean()->IsFalse()) {
fun_name = Handle<Object>(fun->shared()->inferred_name(), this);
}
- SetLocalPropertyNoThrow(stackFrame, function_key, fun_name);
+ CHECK_NOT_EMPTY_HANDLE(this,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, function_key, fun_name, NONE));
}
if (options & StackTrace::kIsEval) {
int type = Smi::cast(script->compilation_type())->value();
Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
factory()->true_value() : factory()->false_value();
- SetLocalPropertyNoThrow(stackFrame, eval_key, is_eval);
+ CHECK_NOT_EMPTY_HANDLE(this,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, eval_key, is_eval, NONE));
}
if (options & StackTrace::kIsConstructor) {
Handle<Object> is_constructor = (frames[i].is_constructor()) ?
factory()->true_value() : factory()->false_value();
- SetLocalPropertyNoThrow(stackFrame, constructor_key, is_constructor);
+ CHECK_NOT_EMPTY_HANDLE(this,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, constructor_key,
+ is_constructor, NONE));
}
- FixedArray::cast(stack_trace->elements())->set(frames_seen, *stackFrame);
+ FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
frames_seen++;
}
it.Advance();
@@ -1734,10 +1751,10 @@ bool Isolate::Init(Deserializer* des) {
regexp_stack_->isolate_ = this;
// Enable logging before setting up the heap
- logger_->Setup();
+ logger_->SetUp();
- CpuProfiler::Setup();
- HeapProfiler::Setup();
+ CpuProfiler::SetUp();
+ HeapProfiler::SetUp();
// Initialize other runtime facilities
#if defined(USE_SIMULATOR)
@@ -1754,10 +1771,10 @@ bool Isolate::Init(Deserializer* des) {
stack_guard_.InitThread(lock);
}
- // Setup the object heap.
+ // SetUp the object heap.
const bool create_heap_objects = (des == NULL);
- ASSERT(!heap_.HasBeenSetup());
- if (!heap_.Setup(create_heap_objects)) {
+ ASSERT(!heap_.HasBeenSetUp());
+ if (!heap_.SetUp(create_heap_objects)) {
V8::SetFatalError();
return false;
}
@@ -1765,7 +1782,7 @@ bool Isolate::Init(Deserializer* des) {
InitializeThreadLocal();
bootstrapper_->Initialize(create_heap_objects);
- builtins_.Setup(create_heap_objects);
+ builtins_.SetUp(create_heap_objects);
// Only preallocate on the first initialization.
if (FLAG_preallocate_message_memory && preallocated_message_space_ == NULL) {
@@ -1784,7 +1801,7 @@ bool Isolate::Init(Deserializer* des) {
}
#ifdef ENABLE_DEBUGGER_SUPPORT
- debug_->Setup(create_heap_objects);
+ debug_->SetUp(create_heap_objects);
#endif
stub_cache_->Initialize(create_heap_objects);
@@ -1805,7 +1822,7 @@ bool Isolate::Init(Deserializer* des) {
deoptimizer_data_ = new DeoptimizerData;
runtime_profiler_ = new RuntimeProfiler(this);
- runtime_profiler_->Setup();
+ runtime_profiler_->SetUp();
// If we are deserializing, log non-function code objects and compiled
// functions found in the snapshot.
diff --git a/deps/v8/src/isolate.h b/deps/v8/src/isolate.h
index c044e1f578..4e5c7dbf51 100644
--- a/deps/v8/src/isolate.h
+++ b/deps/v8/src/isolate.h
@@ -122,6 +122,13 @@ typedef ZoneList<Handle<Object> > ZoneObjectList;
} \
} while (false)
+#define CHECK_NOT_EMPTY_HANDLE(isolate, call) \
+ do { \
+ ASSERT(!(isolate)->has_pending_exception()); \
+ CHECK(!(call).is_null()); \
+ CHECK(!(isolate)->has_pending_exception()); \
+ } while (false)
+
#define RETURN_IF_EMPTY_HANDLE(isolate, call) \
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception())
diff --git a/deps/v8/src/json-parser.h b/deps/v8/src/json-parser.h
index ca796a6990..2b7077e194 100644
--- a/deps/v8/src/json-parser.h
+++ b/deps/v8/src/json-parser.h
@@ -303,11 +303,12 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
uint32_t index;
if (key->AsArrayIndex(&index)) {
- SetOwnElement(json_object, index, value, kNonStrictMode);
+ JSObject::SetOwnElement(json_object, index, value, kNonStrictMode);
} else if (key->Equals(isolate()->heap()->Proto_symbol())) {
SetPrototype(json_object, value);
} else {
- SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ json_object, key, value, NONE);
}
} while (MatchSkipWhiteSpace(','));
if (c0_ != '}') {
diff --git a/deps/v8/src/jsregexp.cc b/deps/v8/src/jsregexp.cc
index 18ff2570e6..15b80d92ce 100644
--- a/deps/v8/src/jsregexp.cc
+++ b/deps/v8/src/jsregexp.cc
@@ -2636,7 +2636,7 @@ void TextNode::MakeCaseIndependent(bool is_ascii) {
TextElement elm = elms_->at(i);
if (elm.type == TextElement::CHAR_CLASS) {
RegExpCharacterClass* cc = elm.data.u_char_class;
- // None of the standard character classses is different in the case
+ // None of the standard character classes is different in the case
// independent case and it slows us down if we don't know that.
if (cc->is_standard()) continue;
ZoneList<CharacterRange>* ranges = cc->ranges();
diff --git a/deps/v8/src/lithium-allocator.cc b/deps/v8/src/lithium-allocator.cc
index c4d8b1e5b7..1601dcf14e 100644
--- a/deps/v8/src/lithium-allocator.cc
+++ b/deps/v8/src/lithium-allocator.cc
@@ -49,13 +49,13 @@ namespace internal {
#define DEFINE_OPERAND_CACHE(name, type) \
name name::cache[name::kNumCachedOperands]; \
- void name::SetupCache() { \
+ void name::SetUpCache() { \
for (int i = 0; i < kNumCachedOperands; i++) { \
cache[i].ConvertTo(type, i); \
} \
} \
static bool name##_initialize() { \
- name::SetupCache(); \
+ name::SetUpCache(); \
return true; \
} \
static bool name##_cache_initialized = name##_initialize();
diff --git a/deps/v8/src/lithium.h b/deps/v8/src/lithium.h
index b605eb97bd..3253520090 100644
--- a/deps/v8/src/lithium.h
+++ b/deps/v8/src/lithium.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -265,7 +265,7 @@ class LConstantOperand: public LOperand {
return reinterpret_cast<LConstantOperand*>(op);
}
- static void SetupCache();
+ static void SetUpCache();
private:
static const int kNumCachedOperands = 128;
@@ -300,7 +300,7 @@ class LStackSlot: public LOperand {
return reinterpret_cast<LStackSlot*>(op);
}
- static void SetupCache();
+ static void SetUpCache();
private:
static const int kNumCachedOperands = 128;
@@ -324,7 +324,7 @@ class LDoubleStackSlot: public LOperand {
return reinterpret_cast<LDoubleStackSlot*>(op);
}
- static void SetupCache();
+ static void SetUpCache();
private:
static const int kNumCachedOperands = 128;
@@ -348,7 +348,7 @@ class LRegister: public LOperand {
return reinterpret_cast<LRegister*>(op);
}
- static void SetupCache();
+ static void SetUpCache();
private:
static const int kNumCachedOperands = 16;
@@ -372,7 +372,7 @@ class LDoubleRegister: public LOperand {
return reinterpret_cast<LDoubleRegister*>(op);
}
- static void SetupCache();
+ static void SetUpCache();
private:
static const int kNumCachedOperands = 16;
@@ -523,8 +523,6 @@ class LEnvironment: public ZoneObject {
LOperand** spilled_double_registers_;
LEnvironment* outer_;
-
- friend class LCodegen;
};
diff --git a/deps/v8/src/liveedit.cc b/deps/v8/src/liveedit.cc
index eb183dac5e..5ff8ff9d3b 100644
--- a/deps/v8/src/liveedit.cc
+++ b/deps/v8/src/liveedit.cc
@@ -54,7 +54,7 @@ void SetElementNonStrict(Handle<JSObject> object,
// are element setters causing exceptions and the debugger context has none
// of these.
Handle<Object> no_failure;
- no_failure = SetElement(object, index, value, kNonStrictMode);
+ no_failure = JSObject::SetElement(object, index, value, kNonStrictMode);
ASSERT(!no_failure.is_null());
USE(no_failure);
}
@@ -1228,7 +1228,7 @@ class RelocInfoBuffer {
V8::FatalProcessOutOfMemory("RelocInfoBuffer::GrowBuffer");
}
- // Setup new buffer.
+ // Set up new buffer.
byte* new_buffer = NewArray<byte>(new_buffer_size);
// Copy the data.
diff --git a/deps/v8/src/liveobjectlist-inl.h b/deps/v8/src/liveobjectlist-inl.h
index f742de3a03..2bc2296e29 100644
--- a/deps/v8/src/liveobjectlist-inl.h
+++ b/deps/v8/src/liveobjectlist-inl.h
@@ -59,7 +59,7 @@ void LiveObjectList::IterateElements(ObjectVisitor* v) {
}
-void LiveObjectList::ProcessNonLive(HeapObject *obj) {
+void LiveObjectList::ProcessNonLive(HeapObject* obj) {
// Only do work if we have at least one list to process.
if (last()) DoProcessNonLive(obj);
}
@@ -93,7 +93,7 @@ LiveObjectList* LiveObjectList::FindLolForId(int id,
template <typename T>
inline LiveObjectList::Element*
LiveObjectList::FindElementFor(T (*GetValue)(LiveObjectList::Element*), T key) {
- LiveObjectList *lol = last();
+ LiveObjectList* lol = last();
while (lol != NULL) {
Element* elements = lol->elements_;
for (int i = 0; i < lol->obj_count_; i++) {
diff --git a/deps/v8/src/liveobjectlist.cc b/deps/v8/src/liveobjectlist.cc
index 408e2a3160..436204e3fa 100644
--- a/deps/v8/src/liveobjectlist.cc
+++ b/deps/v8/src/liveobjectlist.cc
@@ -165,7 +165,7 @@ const char* GetObjectTypeDesc(HeapObject* heap_obj) {
}
-bool IsOfType(LiveObjectType type, HeapObject *obj) {
+bool IsOfType(LiveObjectType type, HeapObject* obj) {
// Note: there are types that are more general (e.g. JSObject) that would
// have passed the Is##type_() test for more specialized types (e.g.
// JSFunction). If we find a more specialized match but we're looking for
@@ -211,7 +211,7 @@ static AllocationSpace FindSpaceFor(String* space_str) {
}
-static bool InSpace(AllocationSpace space, HeapObject *heap_obj) {
+static bool InSpace(AllocationSpace space, HeapObject* heap_obj) {
Heap* heap = ISOLATE->heap();
if (space != LO_SPACE) {
return heap->InSpace(heap_obj, space);
@@ -498,7 +498,7 @@ static void GenerateObjectDesc(HeapObject* obj,
length);
} else if (obj->IsString()) {
- String *str = String::cast(obj);
+ String* str = String::cast(obj);
// Only grab up to 160 chars in case they are double byte.
// We'll only dump 80 of them after we compact them.
const int kMaxCharToDump = 80;
@@ -842,7 +842,7 @@ class LiveObjectSummary {
bool found_root_;
bool found_weak_root_;
- LolFilter *filter_;
+ LolFilter* filter_;
};
@@ -857,8 +857,8 @@ class SummaryWriter {
// A summary writer for filling in a summary of lol lists and diffs.
class LolSummaryWriter: public SummaryWriter {
public:
- LolSummaryWriter(LiveObjectList *older_lol,
- LiveObjectList *newer_lol)
+ LolSummaryWriter(LiveObjectList* older_lol,
+ LiveObjectList* newer_lol)
: older_(older_lol), newer_(newer_lol) {
}
@@ -944,7 +944,7 @@ LiveObjectList::~LiveObjectList() {
int LiveObjectList::GetTotalObjCountAndSize(int* size_p) {
int size = 0;
int count = 0;
- LiveObjectList *lol = this;
+ LiveObjectList* lol = this;
do {
// Only compute total size if requested i.e. when size_p is not null.
if (size_p != NULL) {
@@ -1183,7 +1183,7 @@ MaybeObject* LiveObjectList::Capture() {
// only time we'll actually delete the lol is when we Reset() or if the lol is
// invisible, and its element count reaches 0.
bool LiveObjectList::Delete(int id) {
- LiveObjectList *lol = last();
+ LiveObjectList* lol = last();
while (lol != NULL) {
if (lol->id() == id) {
break;
@@ -1246,8 +1246,8 @@ MaybeObject* LiveObjectList::Dump(int older_id,
newer_id = temp;
}
- LiveObjectList *newer_lol = FindLolForId(newer_id, last());
- LiveObjectList *older_lol = FindLolForId(older_id, newer_lol);
+ LiveObjectList* newer_lol = FindLolForId(newer_id, last());
+ LiveObjectList* older_lol = FindLolForId(older_id, newer_lol);
// If the id is defined, and we can't find a LOL for it, then we have an
// invalid id.
@@ -1365,8 +1365,8 @@ MaybeObject* LiveObjectList::Summarize(int older_id,
newer_id = temp;
}
- LiveObjectList *newer_lol = FindLolForId(newer_id, last());
- LiveObjectList *older_lol = FindLolForId(older_id, newer_lol);
+ LiveObjectList* newer_lol = FindLolForId(newer_id, last());
+ LiveObjectList* older_lol = FindLolForId(older_id, newer_lol);
// If the id is defined, and we can't find a LOL for it, then we have an
// invalid id.
@@ -1626,7 +1626,7 @@ MaybeObject* LiveObjectList::Info(int start_idx, int dump_limit) {
// Deletes all captured lols.
void LiveObjectList::Reset() {
- LiveObjectList *lol = last();
+ LiveObjectList* lol = last();
// Just delete the last. Each lol will delete it's prev automatically.
delete lol;
@@ -1715,8 +1715,8 @@ class LolVisitor: public ObjectVisitor {
inline bool AddRootRetainerIfFound(const LolVisitor& visitor,
LolFilter* filter,
- LiveObjectSummary *summary,
- void (*SetRootFound)(LiveObjectSummary *s),
+ LiveObjectSummary* summary,
+ void (*SetRootFound)(LiveObjectSummary* s),
int start,
int dump_limit,
int* total_count,
@@ -1762,12 +1762,12 @@ inline bool AddRootRetainerIfFound(const LolVisitor& visitor,
}
-inline void SetFoundRoot(LiveObjectSummary *summary) {
+inline void SetFoundRoot(LiveObjectSummary* summary) {
summary->set_found_root();
}
-inline void SetFoundWeakRoot(LiveObjectSummary *summary) {
+inline void SetFoundWeakRoot(LiveObjectSummary* summary) {
summary->set_found_weak_root();
}
@@ -1779,7 +1779,7 @@ int LiveObjectList::GetRetainers(Handle<HeapObject> target,
int dump_limit,
int* total_count,
LolFilter* filter,
- LiveObjectSummary *summary,
+ LiveObjectSummary* summary,
JSFunction* arguments_function,
Handle<Object> error) {
HandleScope scope;
@@ -2267,7 +2267,7 @@ Object* LiveObjectList::GetPath(int obj_id1,
}
-void LiveObjectList::DoProcessNonLive(HeapObject *obj) {
+void LiveObjectList::DoProcessNonLive(HeapObject* obj) {
// We should only be called if we have at least one lol to search.
ASSERT(last() != NULL);
Element* element = last()->Find(obj);
@@ -2284,7 +2284,7 @@ void LiveObjectList::IterateElementsPrivate(ObjectVisitor* v) {
int count = lol->obj_count_;
for (int i = 0; i < count; i++) {
HeapObject** p = &elements[i].obj_;
- v->VisitPointer(reinterpret_cast<Object **>(p));
+ v->VisitPointer(reinterpret_cast<Object** >(p));
}
lol = lol->prev_;
}
@@ -2389,11 +2389,11 @@ void LiveObjectList::GCEpiloguePrivate() {
PurgeDuplicates();
// After the GC, sweep away all free'd Elements and compact.
- LiveObjectList *prev = NULL;
- LiveObjectList *next = NULL;
+ LiveObjectList* prev = NULL;
+ LiveObjectList* next = NULL;
// Iterating from the youngest lol to the oldest lol.
- for (LiveObjectList *lol = last(); lol; lol = prev) {
+ for (LiveObjectList* lol = last(); lol; lol = prev) {
Element* elements = lol->elements_;
prev = lol->prev(); // Save the prev.
@@ -2446,7 +2446,7 @@ void LiveObjectList::GCEpiloguePrivate() {
const int kMaxUnusedSpace = 64;
if (diff > kMaxUnusedSpace) { // Threshold for shrinking.
// Shrink the list.
- Element *new_elements = NewArray<Element>(new_count);
+ Element* new_elements = NewArray<Element>(new_count);
memcpy(new_elements, elements, new_count * sizeof(Element));
DeleteArray<Element>(elements);
diff --git a/deps/v8/src/liveobjectlist.h b/deps/v8/src/liveobjectlist.h
index 65470d7ad9..1aa9196051 100644
--- a/deps/v8/src/liveobjectlist.h
+++ b/deps/v8/src/liveobjectlist.h
@@ -77,7 +77,7 @@ class LiveObjectList {
inline static void GCEpilogue();
inline static void GCPrologue();
inline static void IterateElements(ObjectVisitor* v);
- inline static void ProcessNonLive(HeapObject *obj);
+ inline static void ProcessNonLive(HeapObject* obj);
inline static void UpdateReferencesForScavengeGC();
// Note: LOLs can be listed by calling Dump(0, <lol id>), and 2 LOLs can be
@@ -125,7 +125,7 @@ class LiveObjectList {
static void GCEpiloguePrivate();
static void IterateElementsPrivate(ObjectVisitor* v);
- static void DoProcessNonLive(HeapObject *obj);
+ static void DoProcessNonLive(HeapObject* obj);
static int CompareElement(const Element* a, const Element* b);
@@ -138,7 +138,7 @@ class LiveObjectList {
int dump_limit,
int* total_count,
LolFilter* filter,
- LiveObjectSummary *summary,
+ LiveObjectSummary* summary,
JSFunction* arguments_function,
Handle<Object> error);
@@ -151,7 +151,7 @@ class LiveObjectList {
bool is_tracking_roots);
static bool NeedLOLProcessing() { return (last() != NULL); }
- static void NullifyNonLivePointer(HeapObject **p) {
+ static void NullifyNonLivePointer(HeapObject** p) {
// Mask out the low bit that marks this as a heap object. We'll use this
// cleared bit as an indicator that this pointer needs to be collected.
//
@@ -202,7 +202,7 @@ class LiveObjectList {
int id_;
int capacity_;
int obj_count_;
- Element *elements_;
+ Element* elements_;
// Statics for managing all the lists.
static uint32_t next_element_id_;
diff --git a/deps/v8/src/log.cc b/deps/v8/src/log.cc
index eab26392e3..5e82872da1 100644
--- a/deps/v8/src/log.cc
+++ b/deps/v8/src/log.cc
@@ -1615,7 +1615,7 @@ void Logger::LogAccessorCallbacks() {
}
-bool Logger::Setup() {
+bool Logger::SetUp() {
// Tests and EnsureInitialize() can call this twice in a row. It's harmless.
if (is_initialized_) return true;
is_initialized_ = true;
@@ -1708,9 +1708,9 @@ FILE* Logger::TearDown() {
void Logger::EnableSlidingStateWindow() {
- // If the ticker is NULL, Logger::Setup has not been called yet. In
+ // If the ticker is NULL, Logger::SetUp has not been called yet. In
// that case, we set the sliding_state_window flag so that the
- // sliding window computation will be started when Logger::Setup is
+ // sliding window computation will be started when Logger::SetUp is
// called.
if (ticker_ == NULL) {
FLAG_sliding_state_window = true;
diff --git a/deps/v8/src/log.h b/deps/v8/src/log.h
index 677dada03a..86bcad69aa 100644
--- a/deps/v8/src/log.h
+++ b/deps/v8/src/log.h
@@ -150,14 +150,14 @@ class Logger {
#undef DECLARE_ENUM
// Acquires resources for logging if the right flags are set.
- bool Setup();
+ bool SetUp();
void EnsureTickerStarted();
void EnsureTickerStopped();
Sampler* sampler();
- // Frees resources acquired in Setup.
+ // Frees resources acquired in SetUp.
// When a temporary file is used for the log, returns its stream descriptor,
// leaving the file open.
FILE* TearDown();
@@ -411,7 +411,7 @@ class Logger {
NameMap* address_to_name_map_;
// Guards against multiple calls to TearDown() that can happen in some tests.
- // 'true' between Setup() and TearDown().
+ // 'true' between SetUp() and TearDown().
bool is_initialized_;
// Support for 'incremental addresses' in compressed logs:
diff --git a/deps/v8/src/mark-compact.cc b/deps/v8/src/mark-compact.cc
index 1fb5d5f438..6d7fbdff2b 100644
--- a/deps/v8/src/mark-compact.cc
+++ b/deps/v8/src/mark-compact.cc
@@ -3641,6 +3641,7 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
PrintF("Sweeping 0x%" V8PRIxPTR " lazily postponed.\n",
reinterpret_cast<intptr_t>(p));
}
+ space->MarkPageForLazySweeping(p);
continue;
}
diff --git a/deps/v8/src/mips/assembler-mips-inl.h b/deps/v8/src/mips/assembler-mips-inl.h
index 2ba9760e2a..0788e73ef6 100644
--- a/deps/v8/src/mips/assembler-mips-inl.h
+++ b/deps/v8/src/mips/assembler-mips-inl.h
@@ -133,7 +133,7 @@ Object* RelocInfo::target_object() {
}
-Handle<Object> RelocInfo::target_object_handle(Assembler *origin) {
+Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
return Handle<Object>(reinterpret_cast<Object**>(
Assembler::target_address_at(pc_)));
diff --git a/deps/v8/src/mips/assembler-mips.cc b/deps/v8/src/mips/assembler-mips.cc
index e933181d41..85b6ed802a 100644
--- a/deps/v8/src/mips/assembler-mips.cc
+++ b/deps/v8/src/mips/assembler-mips.cc
@@ -301,7 +301,7 @@ Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
own_buffer_ = false;
}
- // Setup buffer pointers.
+ // Set up buffer pointers.
ASSERT(buffer_ != NULL);
pc_ = buffer_;
reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
@@ -337,7 +337,7 @@ Assembler::~Assembler() {
void Assembler::GetCode(CodeDesc* desc) {
ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
- // Setup code descriptor.
+ // Set up code descriptor.
desc->buffer = buffer_;
desc->buffer_size = buffer_size_;
desc->instr_size = pc_offset();
@@ -1970,7 +1970,7 @@ void Assembler::GrowBuffer() {
}
CHECK_GT(desc.buffer_size, 0); // No overflow.
- // Setup new buffer.
+ // Set up new buffer.
desc.buffer = NewArray<byte>(desc.buffer_size);
desc.instr_size = pc_offset();
diff --git a/deps/v8/src/mips/builtins-mips.cc b/deps/v8/src/mips/builtins-mips.cc
index 46a912bd59..9e108c9d1f 100644
--- a/deps/v8/src/mips/builtins-mips.cc
+++ b/deps/v8/src/mips/builtins-mips.cc
@@ -339,7 +339,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
t1,
call_generic_code);
__ IncrementCounter(counters->array_function_native(), 1, a3, t0);
- // Setup return value, remove receiver from stack and return.
+ // Set up return value, remove receiver from stack and return.
__ mov(v0, a2);
__ Addu(sp, sp, Operand(kPointerSize));
__ Ret();
@@ -382,7 +382,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
call_generic_code);
__ IncrementCounter(counters->array_function_native(), 1, a2, t0);
- // Setup return value, remove receiver and argument from stack and return.
+ // Set up return value, remove receiver and argument from stack and return.
__ mov(v0, a3);
__ Addu(sp, sp, Operand(2 * kPointerSize));
__ Ret();
@@ -981,10 +981,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
// sp[4]: number of arguments (smi-tagged)
__ lw(a3, MemOperand(sp, 4 * kPointerSize));
- // Setup pointer to last argument.
+ // Set up pointer to last argument.
__ Addu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
- // Setup number of arguments for function call below.
+ // Set up number of arguments for function call below.
__ srl(a0, a3, kSmiTagSize);
// Copy arguments and receiver to the expression stack.
@@ -1114,10 +1114,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// Set up the context from the function argument.
__ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
- // Set up the roots register.
- ExternalReference roots_array_start =
- ExternalReference::roots_array_start(masm->isolate());
- __ li(s6, Operand(roots_array_start));
+ __ InitializeRootRegister();
// Push the function and the receiver onto the stack.
__ Push(a1, a2);
diff --git a/deps/v8/src/mips/code-stubs-mips.cc b/deps/v8/src/mips/code-stubs-mips.cc
index 3e811bd7cb..57091ef60b 100644
--- a/deps/v8/src/mips/code-stubs-mips.cc
+++ b/deps/v8/src/mips/code-stubs-mips.cc
@@ -157,13 +157,13 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
// Load the function from the stack.
__ lw(a3, MemOperand(sp, 0));
- // Setup the object header.
+ // Set up the object header.
__ LoadRoot(a2, Heap::kFunctionContextMapRootIndex);
__ sw(a2, FieldMemOperand(v0, HeapObject::kMapOffset));
__ li(a2, Operand(Smi::FromInt(length)));
__ sw(a2, FieldMemOperand(v0, FixedArray::kLengthOffset));
- // Setup the fixed slots.
+ // Set up the fixed slots.
__ li(a1, Operand(Smi::FromInt(0)));
__ sw(a3, MemOperand(v0, Context::SlotOffset(Context::CLOSURE_INDEX)));
__ sw(cp, MemOperand(v0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
@@ -208,7 +208,7 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
// Load the serialized scope info from the stack.
__ lw(a1, MemOperand(sp, 1 * kPointerSize));
- // Setup the object header.
+ // Set up the object header.
__ LoadRoot(a2, Heap::kBlockContextMapRootIndex);
__ sw(a2, FieldMemOperand(v0, HeapObject::kMapOffset));
__ li(a2, Operand(Smi::FromInt(length)));
@@ -229,7 +229,7 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ lw(a3, ContextOperand(a3, Context::CLOSURE_INDEX));
__ bind(&after_sentinel);
- // Setup the fixed slots.
+ // Set up the fixed slots.
__ sw(a3, ContextOperand(v0, Context::CLOSURE_INDEX));
__ sw(cp, ContextOperand(v0, Context::PREVIOUS_INDEX));
__ sw(a1, ContextOperand(v0, Context::EXTENSION_INDEX));
@@ -726,7 +726,7 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
__ Subu(int_scratch, zero_reg, int_scratch);
__ bind(&skip_sub);
- // Get mantisssa[51:20].
+ // Get mantissa[51:20].
// Get the position of the first set bit.
__ clz(dst1, int_scratch);
@@ -971,7 +971,7 @@ void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm,
// non zero bits left. So we need the (30 - exponent) last bits of the
// 31 higher bits of the mantissa to be null.
// Because bits [21:0] are null, we can check instead that the
- // (32 - exponent) last bits of the 32 higher bits of the mantisssa are null.
+ // (32 - exponent) last bits of the 32 higher bits of the mantissa are null.
// Get the 32 higher bits of the mantissa in dst.
__ Ext(dst,
@@ -4005,7 +4005,7 @@ void CEntryStub::Generate(MacroAssembler* masm) {
FrameScope scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(save_doubles_);
- // Setup argc and the builtin function in callee-saved registers.
+ // Set up argc and the builtin function in callee-saved registers.
__ mov(s0, a0);
__ mov(s2, a1);
@@ -4097,7 +4097,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
isolate)));
__ lw(t0, MemOperand(t0));
__ Push(t3, t2, t1, t0);
- // Setup frame pointer for the frame to be pushed.
+ // Set up frame pointer for the frame to be pushed.
__ addiu(fp, sp, -EntryFrameConstants::kCallerFPOffset);
// Registers:
@@ -4584,7 +4584,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
__ sw(a3, FieldMemOperand(v0, i));
}
- // Setup the callee in-object property.
+ // Set up the callee in-object property.
STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
__ lw(a3, MemOperand(sp, 2 * kPointerSize));
const int kCalleeOffset = JSObject::kHeaderSize +
@@ -4597,7 +4597,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
Heap::kArgumentsLengthIndex * kPointerSize;
__ sw(a2, FieldMemOperand(v0, kLengthOffset));
- // Setup the elements pointer in the allocated arguments object.
+ // Set up the elements pointer in the allocated arguments object.
// If we allocated a parameter map, t0 will point there, otherwise
// it will point to the backing store.
__ Addu(t0, v0, Operand(Heap::kArgumentsObjectSize));
@@ -4699,7 +4699,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
__ Ret();
// Do the runtime call to allocate the arguments object.
- // a2 = argument count (taggged)
+ // a2 = argument count (tagged)
__ bind(&runtime);
__ sw(a2, MemOperand(sp, 0 * kPointerSize)); // Patch argument count.
__ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
@@ -4774,7 +4774,7 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Get the parameters pointer from the stack.
__ lw(a2, MemOperand(sp, 1 * kPointerSize));
- // Setup the elements pointer in the allocated arguments object and
+ // Set up the elements pointer in the allocated arguments object and
// initialize the header in the elements fixed array.
__ Addu(t0, v0, Operand(Heap::kArgumentsObjectSizeStrict));
__ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
@@ -4786,7 +4786,7 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Copy the fixed array slots.
Label loop;
- // Setup t0 to point to the first array slot.
+ // Set up t0 to point to the first array slot.
__ Addu(t0, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ bind(&loop);
// Pre-decrement a2 with kPointerSize on each iteration.
@@ -5425,7 +5425,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// of the original receiver from the call site).
__ bind(&non_function);
__ sw(a1, MemOperand(sp, argc_ * kPointerSize));
- __ li(a0, Operand(argc_)); // Setup the number of arguments.
+ __ li(a0, Operand(argc_)); // Set up the number of arguments.
__ mov(a2, zero_reg);
__ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION);
__ SetCallKind(t1, CALL_AS_METHOD);
@@ -5927,7 +5927,7 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
Register hash,
Register character) {
// hash = seed + character + ((seed + character) << 10);
- __ LoadRoot(hash, Heap::kStringHashSeedRootIndex);
+ __ LoadRoot(hash, Heap::kHashSeedRootIndex);
// Untag smi seed and add the character.
__ SmiUntag(hash);
__ addu(hash, hash, character);
@@ -5954,7 +5954,7 @@ void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm,
void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
- Register hash) {
+ Register hash) {
// hash += hash << 3;
__ sll(at, hash, 3);
__ addu(hash, hash, at);
@@ -5965,12 +5965,11 @@ void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
__ sll(at, hash, 15);
__ addu(hash, hash, at);
- uint32_t kHashShiftCutOffMask = (1 << (32 - String::kHashShift)) - 1;
- __ li(at, Operand(kHashShiftCutOffMask));
+ __ li(at, Operand(String::kHashBitMask));
__ and_(hash, hash, at);
// if (hash == 0) hash = 27;
- __ ori(at, zero_reg, 27);
+ __ ori(at, zero_reg, StringHasher::kZeroHash);
__ movz(hash, at, hash);
}
diff --git a/deps/v8/src/mips/constants-mips.h b/deps/v8/src/mips/constants-mips.h
index 4f486c1c04..210becb449 100644
--- a/deps/v8/src/mips/constants-mips.h
+++ b/deps/v8/src/mips/constants-mips.h
@@ -125,7 +125,7 @@ class Registers {
struct RegisterAlias {
int reg;
- const char *name;
+ const char* name;
};
static const int32_t kMaxValue = 0x7fffffff;
@@ -147,7 +147,7 @@ class FPURegisters {
struct RegisterAlias {
int creg;
- const char *name;
+ const char* name;
};
private:
diff --git a/deps/v8/src/mips/cpu-mips.cc b/deps/v8/src/mips/cpu-mips.cc
index 26e95fb24c..a1e062c803 100644
--- a/deps/v8/src/mips/cpu-mips.cc
+++ b/deps/v8/src/mips/cpu-mips.cc
@@ -47,7 +47,7 @@ namespace v8 {
namespace internal {
-void CPU::Setup() {
+void CPU::SetUp() {
CpuFeatures::Probe();
}
diff --git a/deps/v8/src/mips/deoptimizer-mips.cc b/deps/v8/src/mips/deoptimizer-mips.cc
index a27c61cb2d..44af3d7b29 100644
--- a/deps/v8/src/mips/deoptimizer-mips.cc
+++ b/deps/v8/src/mips/deoptimizer-mips.cc
@@ -326,7 +326,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
output_[0] = input_;
output_[0]->SetPc(reinterpret_cast<uint32_t>(from_));
} else {
- // Setup the frame pointer and the context pointer.
+ // Set up the frame pointer and the context pointer.
output_[0]->SetRegister(fp.code(), input_->GetRegister(fp.code()));
output_[0]->SetRegister(cp.code(), input_->GetRegister(cp.code()));
@@ -733,10 +733,7 @@ void Deoptimizer::EntryGenerator::Generate() {
}
}
- // Set up the roots register.
- ExternalReference roots_array_start =
- ExternalReference::roots_array_start(isolate);
- __ li(roots, Operand(roots_array_start));
+ __ InitializeRootRegister();
__ pop(at); // Get continuation, leave pc on stack.
__ pop(ra);
diff --git a/deps/v8/src/mips/full-codegen-mips.cc b/deps/v8/src/mips/full-codegen-mips.cc
index 1e950e5f51..7394077f0a 100644
--- a/deps/v8/src/mips/full-codegen-mips.cc
+++ b/deps/v8/src/mips/full-codegen-mips.cc
@@ -1017,7 +1017,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ lw(a1, FieldMemOperand(a1, DescriptorArray::kEnumerationIndexOffset));
__ lw(a2, FieldMemOperand(a1, DescriptorArray::kEnumCacheBridgeCacheOffset));
- // Setup the four remaining stack slots.
+ // Set up the four remaining stack slots.
__ push(v0); // Map.
__ lw(a1, FieldMemOperand(a2, FixedArray::kLengthOffset));
__ li(a0, Operand(Smi::FromInt(0)));
diff --git a/deps/v8/src/mips/lithium-codegen-mips.cc b/deps/v8/src/mips/lithium-codegen-mips.cc
index 06e886c6bb..de6400708f 100644
--- a/deps/v8/src/mips/lithium-codegen-mips.cc
+++ b/deps/v8/src/mips/lithium-codegen-mips.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -2794,7 +2794,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
__ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
__ Call(at);
- // Setup deoptimization.
+ // Set up deoptimization.
RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
// Restore context.
@@ -3095,6 +3095,27 @@ void LCodeGen::DoPower(LPower* instr) {
}
+void LCodeGen::DoRandom(LRandom* instr) {
+ // Having marked this instruction as a call we can use any
+ // registers.
+ ASSERT(ToDoubleRegister(instr->result()).is(f0));
+ ASSERT(ToRegister(instr->InputAt(0)).is(a0));
+
+ __ PrepareCallCFunction(1, a1);
+ __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalContextOffset));
+ __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
+
+ // 0x41300000 is the top half of 1.0 x 2^20 as a double.
+ __ li(a2, Operand(0x41300000));
+ // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU.
+ __ Move(f12, v0, a2);
+ // Move 0x4130000000000000 to FPU.
+ __ Move(f14, zero_reg, a2);
+ // Subtract to get the result.
+ __ sub_d(f0, f12, f14);
+}
+
+
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
ASSERT(ToDoubleRegister(instr->result()).is(f4));
TranscendentalCacheStub stub(TranscendentalCache::LOG,
diff --git a/deps/v8/src/mips/lithium-codegen-mips.h b/deps/v8/src/mips/lithium-codegen-mips.h
index 68a7c5b1aa..2a54681990 100644
--- a/deps/v8/src/mips/lithium-codegen-mips.h
+++ b/deps/v8/src/mips/lithium-codegen-mips.h
@@ -148,9 +148,9 @@ class LCodeGen BASE_EMBEDDED {
Scope* scope() const { return scope_; }
HGraph* graph() const { return chunk_->graph(); }
- Register scratch0() { return lithiumScratchReg; }
- Register scratch1() { return lithiumScratchReg2; }
- DoubleRegister double_scratch0() { return lithiumScratchDouble; }
+ Register scratch0() { return kLithiumScratchReg; }
+ Register scratch1() { return kLithiumScratchReg2; }
+ DoubleRegister double_scratch0() { return kLithiumScratchDouble; }
int GetNextEmittedBlock(int block);
LInstruction* GetNextInstruction();
@@ -423,7 +423,7 @@ class LDeferredCode: public ZoneObject {
virtual void Generate() = 0;
virtual LInstruction* instr() = 0;
- void SetExit(Label *exit) { external_exit_ = exit; }
+ void SetExit(Label* exit) { external_exit_ = exit; }
Label* entry() { return &entry_; }
Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
int instruction_index() const { return instruction_index_; }
diff --git a/deps/v8/src/mips/lithium-gap-resolver-mips.cc b/deps/v8/src/mips/lithium-gap-resolver-mips.cc
index 2e5c64e7a2..279a95ece4 100644
--- a/deps/v8/src/mips/lithium-gap-resolver-mips.cc
+++ b/deps/v8/src/mips/lithium-gap-resolver-mips.cc
@@ -33,8 +33,8 @@
namespace v8 {
namespace internal {
-static const Register kSavedValueRegister = lithiumScratchReg;
-static const DoubleRegister kSavedDoubleValueRegister = lithiumScratchDouble;
+static const Register kSavedValueRegister = kLithiumScratchReg;
+static const DoubleRegister kSavedDoubleValueRegister = kLithiumScratchDouble;
LGapResolver::LGapResolver(LCodeGen* owner)
: cgen_(owner),
diff --git a/deps/v8/src/mips/lithium-mips.cc b/deps/v8/src/mips/lithium-mips.cc
index 634b706108..b66b98f208 100644
--- a/deps/v8/src/mips/lithium-mips.cc
+++ b/deps/v8/src/mips/lithium-mips.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -1038,14 +1038,23 @@ LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
- HValue* v = instr->value();
- if (v->EmitAtUses()) {
- HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
+ HValue* value = instr->value();
+ if (value->EmitAtUses()) {
+ HBasicBlock* successor = HConstant::cast(value)->ToBoolean()
? instr->FirstSuccessor()
: instr->SecondSuccessor();
return new LGoto(successor->block_id());
}
- return AssignEnvironment(new LBranch(UseRegister(v)));
+
+ LBranch* result = new LBranch(UseRegister(value));
+ // Tagged values that are not known smis or booleans require a
+ // deoptimization environment.
+ Representation rep = value->representation();
+ HType type = value->type();
+ if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean()) {
+ return AssignEnvironment(result);
+ }
+ return result;
}
@@ -1345,7 +1354,12 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
} else {
left = UseRegisterAtStart(instr->LeastConstantOperand());
}
- return AssignEnvironment(DefineAsRegister(new LMulI(left, right, temp)));
+ LMulI* mul = new LMulI(left, right, temp);
+ if (instr->CheckFlag(HValue::kCanOverflow) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ AssignEnvironment(mul);
+ }
+ return DefineAsRegister(mul);
} else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::MUL, instr);
@@ -1414,6 +1428,15 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
}
+LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->global_object()->representation().IsTagged());
+ LOperand* global_object = UseFixed(instr->global_object(), a0);
+ LRandom* result = new LRandom(global_object);
+ return MarkAsCall(DefineFixedDouble(result, f0), instr);
+}
+
+
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
Representation r = instr->GetInputRepresentation();
ASSERT(instr->left()->representation().IsTagged());
@@ -1558,7 +1581,7 @@ LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
LOperand* object = UseRegister(instr->value());
LValueOf* result = new LValueOf(object, TempRegister());
- return AssignEnvironment(DefineAsRegister(result));
+ return DefineAsRegister(result);
}
@@ -1877,7 +1900,8 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterAtStart(instr->key());
LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
- return AssignEnvironment(DefineAsRegister(result));
+ if (instr->RequiresHoleCheck()) AssignEnvironment(result);
+ return DefineAsRegister(result);
}
diff --git a/deps/v8/src/mips/lithium-mips.h b/deps/v8/src/mips/lithium-mips.h
index da59dd8b0c..069a0251fd 100644
--- a/deps/v8/src/mips/lithium-mips.h
+++ b/deps/v8/src/mips/lithium-mips.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -141,6 +141,7 @@ class LCodeGen;
V(Parameter) \
V(Power) \
V(PushArgument) \
+ V(Random) \
V(RegExpLiteral) \
V(Return) \
V(ShiftI) \
@@ -1026,6 +1027,17 @@ class LPower: public LTemplateInstruction<1, 2, 0> {
};
+class LRandom: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LRandom(LOperand* global_object) {
+ inputs_[0] = global_object;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Random, "random")
+ DECLARE_HYDROGEN_ACCESSOR(Random)
+};
+
+
class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
public:
LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
diff --git a/deps/v8/src/mips/macro-assembler-mips.cc b/deps/v8/src/mips/macro-assembler-mips.cc
index cdacbf3c0d..4517fe1818 100644
--- a/deps/v8/src/mips/macro-assembler-mips.cc
+++ b/deps/v8/src/mips/macro-assembler-mips.cc
@@ -252,6 +252,12 @@ void MacroAssembler::RecordWrite(Register object,
// registers are cp.
ASSERT(!address.is(cp) && !value.is(cp));
+ if (emit_debug_code()) {
+ lw(at, MemOperand(address));
+ Assert(
+ eq, "Wrong address or value passed to RecordWrite", at, Operand(value));
+ }
+
Label done;
if (smi_check == INLINE_SMI_CHECK) {
@@ -297,7 +303,7 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
SaveFPRegsMode fp_mode,
RememberedSetFinalAction and_then) {
Label done;
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
Label ok;
JumpIfNotInNewSpace(object, scratch, &ok);
stop("Remembered set pointer is in new space");
@@ -409,6 +415,44 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
}
+void MacroAssembler::GetNumberHash(Register reg0, Register scratch) {
+ // First of all we assign the hash seed to scratch.
+ LoadRoot(scratch, Heap::kHashSeedRootIndex);
+ SmiUntag(scratch);
+
+ // Xor original key with a seed.
+ xor_(reg0, reg0, scratch);
+
+ // Compute the hash code from the untagged key. This must be kept in sync
+ // with ComputeIntegerHash in utils.h.
+ //
+ // hash = ~hash + (hash << 15);
+ nor(scratch, reg0, zero_reg);
+ sll(at, reg0, 15);
+ addu(reg0, scratch, at);
+
+ // hash = hash ^ (hash >> 12);
+ srl(at, reg0, 12);
+ xor_(reg0, reg0, at);
+
+ // hash = hash + (hash << 2);
+ sll(at, reg0, 2);
+ addu(reg0, reg0, at);
+
+ // hash = hash ^ (hash >> 4);
+ srl(at, reg0, 4);
+ xor_(reg0, reg0, at);
+
+ // hash = hash * 2057;
+ li(scratch, Operand(2057));
+ mul(reg0, reg0, scratch);
+
+ // hash = hash ^ (hash >> 16);
+ srl(at, reg0, 16);
+ xor_(reg0, reg0, at);
+}
+
+
void MacroAssembler::LoadFromNumberDictionary(Label* miss,
Register elements,
Register key,
@@ -440,36 +484,10 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
// at - Temporary (avoid MacroAssembler instructions also using 'at').
Label done;
- // Compute the hash code from the untagged key. This must be kept in sync
- // with ComputeIntegerHash in utils.h.
- //
- // hash = ~hash + (hash << 15);
- nor(reg1, reg0, zero_reg);
- sll(at, reg0, 15);
- addu(reg0, reg1, at);
-
- // hash = hash ^ (hash >> 12);
- srl(at, reg0, 12);
- xor_(reg0, reg0, at);
-
- // hash = hash + (hash << 2);
- sll(at, reg0, 2);
- addu(reg0, reg0, at);
-
- // hash = hash ^ (hash >> 4);
- srl(at, reg0, 4);
- xor_(reg0, reg0, at);
-
- // hash = hash * 2057;
- li(reg1, Operand(2057));
- mul(reg0, reg0, reg1);
-
- // hash = hash ^ (hash >> 16);
- srl(at, reg0, 16);
- xor_(reg0, reg0, at);
+ GetNumberHash(reg0, reg1);
// Compute the capacity mask.
- lw(reg1, FieldMemOperand(elements, NumberDictionary::kCapacityOffset));
+ lw(reg1, FieldMemOperand(elements, SeededNumberDictionary::kCapacityOffset));
sra(reg1, reg1, kSmiTagSize);
Subu(reg1, reg1, Operand(1));
@@ -480,12 +498,12 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
mov(reg2, reg0);
// Compute the masked index: (hash + i + i * i) & mask.
if (i > 0) {
- Addu(reg2, reg2, Operand(NumberDictionary::GetProbeOffset(i)));
+ Addu(reg2, reg2, Operand(SeededNumberDictionary::GetProbeOffset(i)));
}
and_(reg2, reg2, reg1);
// Scale the index by multiplying by the element size.
- ASSERT(NumberDictionary::kEntrySize == 3);
+ ASSERT(SeededNumberDictionary::kEntrySize == 3);
sll(at, reg2, 1); // 2x.
addu(reg2, reg2, at); // reg2 = reg2 * 3.
@@ -493,7 +511,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
sll(at, reg2, kPointerSizeLog2);
addu(reg2, elements, at);
- lw(at, FieldMemOperand(reg2, NumberDictionary::kElementsStartOffset));
+ lw(at, FieldMemOperand(reg2, SeededNumberDictionary::kElementsStartOffset));
if (i != kProbes - 1) {
Branch(&done, eq, key, Operand(at));
} else {
@@ -505,14 +523,14 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
// Check that the value is a normal property.
// reg2: elements + (index * kPointerSize).
const int kDetailsOffset =
- NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
+ SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
lw(reg1, FieldMemOperand(reg2, kDetailsOffset));
And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask)));
Branch(miss, ne, at, Operand(zero_reg));
// Get the value at the masked, scaled index and return.
const int kValueOffset =
- NumberDictionary::kElementsStartOffset + kPointerSize;
+ SeededNumberDictionary::kElementsStartOffset + kPointerSize;
lw(result, FieldMemOperand(reg2, kValueOffset));
}
@@ -4261,7 +4279,7 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
void MacroAssembler::EnterExitFrame(bool save_doubles,
int stack_space) {
- // Setup the frame structure on the stack.
+ // Set up the frame structure on the stack.
STATIC_ASSERT(2 * kPointerSize == ExitFrameConstants::kCallerSPDisplacement);
STATIC_ASSERT(1 * kPointerSize == ExitFrameConstants::kCallerPCOffset);
STATIC_ASSERT(0 * kPointerSize == ExitFrameConstants::kCallerFPOffset);
@@ -4279,7 +4297,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles,
addiu(sp, sp, -4 * kPointerSize);
sw(ra, MemOperand(sp, 3 * kPointerSize));
sw(fp, MemOperand(sp, 2 * kPointerSize));
- addiu(fp, sp, 2 * kPointerSize); // Setup new frame pointer.
+ addiu(fp, sp, 2 * kPointerSize); // Set up new frame pointer.
if (emit_debug_code()) {
sw(zero_reg, MemOperand(fp, ExitFrameConstants::kSPOffset));
@@ -4826,7 +4844,7 @@ void MacroAssembler::EnsureNotWhite(
And(t8, mask_scratch, load_scratch);
Branch(&done, ne, t8, Operand(zero_reg));
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// Check for impossible bit pattern.
Label ok;
// sll may overflow, making the check conservative.
diff --git a/deps/v8/src/mips/macro-assembler-mips.h b/deps/v8/src/mips/macro-assembler-mips.h
index bd5b94f57c..eb9cf6e574 100644
--- a/deps/v8/src/mips/macro-assembler-mips.h
+++ b/deps/v8/src/mips/macro-assembler-mips.h
@@ -53,13 +53,13 @@ class JumpTarget;
// Register aliases.
// cp is assumed to be a callee saved register.
-const Register lithiumScratchReg = s3; // Scratch register.
-const Register lithiumScratchReg2 = s4; // Scratch register.
-const Register condReg = s5; // Simulated (partial) condition code for mips.
-const Register roots = s6; // Roots array pointer.
+const Register kLithiumScratchReg = s3; // Scratch register.
+const Register kLithiumScratchReg2 = s4; // Scratch register.
+const Register kCondReg = s5; // Simulated (partial) condition code for mips.
+const Register kRootRegister = s6; // Roots array pointer.
const Register cp = s7; // JavaScript context pointer.
const Register fp = s8_fp; // Alias for fp.
-const DoubleRegister lithiumScratchDouble = f30; // Double scratch register.
+const DoubleRegister kLithiumScratchDouble = f30; // Double scratch register.
// Flags used for the AllocateInNewSpace functions.
enum AllocationFlags {
@@ -405,6 +405,7 @@ class MacroAssembler: public Assembler {
Register scratch,
Label* miss);
+ void GetNumberHash(Register reg0, Register scratch);
void LoadFromNumberDictionary(Label* miss,
Register elements,
@@ -789,11 +790,16 @@ class MacroAssembler: public Assembler {
Register map,
Register scratch);
+ void InitializeRootRegister() {
+ ExternalReference roots_array_start =
+ ExternalReference::roots_array_start(isolate());
+ li(kRootRegister, Operand(roots_array_start));
+ }
// -------------------------------------------------------------------------
// JavaScript invokes.
- // Setup call kind marking in t1. The method takes t1 as an
+ // Set up call kind marking in t1. The method takes t1 as an
// explicit first parameter to make the code more readable at the
// call sites.
void SetCallKind(Register dst, CallKind kind);
diff --git a/deps/v8/src/mips/simulator-mips.cc b/deps/v8/src/mips/simulator-mips.cc
index f70775d86b..191c2cafd5 100644
--- a/deps/v8/src/mips/simulator-mips.cc
+++ b/deps/v8/src/mips/simulator-mips.cc
@@ -888,7 +888,7 @@ Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
isolate_->set_simulator_i_cache(i_cache_);
}
Initialize(isolate);
- // Setup simulator support first. Some of this information is needed to
+ // Set up simulator support first. Some of this information is needed to
// setup the architecture state.
stack_ = reinterpret_cast<char*>(malloc(stack_size_));
pc_modified_ = false;
@@ -897,7 +897,7 @@ Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
break_pc_ = NULL;
break_instr_ = 0;
- // Setup architecture state.
+ // Set up architecture state.
// All registers are initialized to zero to start with.
for (int i = 0; i < kNumSimuRegisters; i++) {
registers_[i] = 0;
@@ -1944,7 +1944,7 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
// Next pc
int32_t next_pc = 0;
- // Setup the variables if needed before executing the instruction.
+ // Set up the variables if needed before executing the instruction.
ConfigureTypeRegister(instr,
alu_out,
i64hilo,
@@ -2711,7 +2711,7 @@ void Simulator::Execute() {
int32_t Simulator::Call(byte* entry, int argument_count, ...) {
va_list parameters;
va_start(parameters, argument_count);
- // Setup arguments.
+ // Set up arguments.
// First four arguments passed in registers.
ASSERT(argument_count >= 4);
@@ -2758,7 +2758,7 @@ int32_t Simulator::Call(byte* entry, int argument_count, ...) {
int32_t sp_val = get_register(sp);
int32_t fp_val = get_register(fp);
- // Setup the callee-saved registers with a known value. To be able to check
+ // Set up the callee-saved registers with a known value. To be able to check
// that they are preserved properly across JS execution.
int32_t callee_saved_value = icount_;
set_register(s0, callee_saved_value);
diff --git a/deps/v8/src/mips/stub-cache-mips.cc b/deps/v8/src/mips/stub-cache-mips.cc
index a94e277a50..bf01861a61 100644
--- a/deps/v8/src/mips/stub-cache-mips.cc
+++ b/deps/v8/src/mips/stub-cache-mips.cc
@@ -1173,7 +1173,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
__ EnterExitFrame(false, kApiStackSpace);
// Create AccessorInfo instance on the stack above the exit frame with
- // scratch2 (internal::Object **args_) as the data.
+ // scratch2 (internal::Object** args_) as the data.
__ sw(a2, MemOperand(sp, kPointerSize));
// a2 (second argument - see note above) = AccessorInfo&
__ Addu(a2, sp, kPointerSize);
@@ -2430,7 +2430,7 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
__ sw(a3, MemOperand(sp, argc * kPointerSize));
}
- // Setup the context (function already in r1).
+ // Set up the context (function already in r1).
__ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
// Jump to the cached code (tail call).
diff --git a/deps/v8/src/objects-debug.cc b/deps/v8/src/objects-debug.cc
index 64bda9473f..5c68ddff7f 100644
--- a/deps/v8/src/objects-debug.cc
+++ b/deps/v8/src/objects-debug.cc
@@ -602,6 +602,13 @@ void AccessorInfo::AccessorInfoVerify() {
}
+void AccessorPair::AccessorPairVerify() {
+ CHECK(IsAccessorPair());
+ VerifyPointer(getter());
+ VerifyPointer(setter());
+}
+
+
void AccessCheckInfo::AccessCheckInfoVerify() {
CHECK(IsAccessCheckInfo());
VerifyPointer(named_callback());
@@ -739,7 +746,7 @@ void JSObject::IncrementSpillStatistics(SpillInformation* info) {
break;
}
case DICTIONARY_ELEMENTS: {
- NumberDictionary* dict = element_dictionary();
+ SeededNumberDictionary* dict = element_dictionary();
info->number_of_slow_used_elements_ += dict->NumberOfElements();
info->number_of_slow_unused_elements_ +=
dict->Capacity() - dict->NumberOfElements();
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h
index c5cf060829..2e9ccc1fa2 100644
--- a/deps/v8/src/objects-inl.h
+++ b/deps/v8/src/objects-inl.h
@@ -1725,7 +1725,7 @@ void FixedDoubleArray::Initialize(FixedArray* from) {
}
-void FixedDoubleArray::Initialize(NumberDictionary* from) {
+void FixedDoubleArray::Initialize(SeededNumberDictionary* from) {
int offset = kHeaderSize;
for (int current = 0; current < length(); ++current) {
WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
@@ -2057,7 +2057,7 @@ int HashTable<Shape, Key>::FindEntry(Key key) {
template<typename Shape, typename Key>
int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
uint32_t capacity = Capacity();
- uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
+ uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
uint32_t count = 1;
// EnsureCapacity will guarantee the hash table is never full.
while (true) {
@@ -2072,14 +2072,14 @@ int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
}
-bool NumberDictionary::requires_slow_elements() {
+bool SeededNumberDictionary::requires_slow_elements() {
Object* max_index_object = get(kMaxNumberKeyIndex);
if (!max_index_object->IsSmi()) return false;
return 0 !=
(Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
}
-uint32_t NumberDictionary::max_number_key() {
+uint32_t SeededNumberDictionary::max_number_key() {
ASSERT(!requires_slow_elements());
Object* max_index_object = get(kMaxNumberKeyIndex);
if (!max_index_object->IsSmi()) return 0;
@@ -2087,7 +2087,7 @@ uint32_t NumberDictionary::max_number_key() {
return value >> kRequiresSlowElementsTagSize;
}
-void NumberDictionary::set_requires_slow_elements() {
+void SeededNumberDictionary::set_requires_slow_elements() {
set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
}
@@ -3386,6 +3386,9 @@ ACCESSORS(AccessorInfo, data, Object, kDataOffset)
ACCESSORS(AccessorInfo, name, Object, kNameOffset)
ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
+ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
+ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
+
ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
@@ -4296,9 +4299,9 @@ StringDictionary* JSObject::property_dictionary() {
}
-NumberDictionary* JSObject::element_dictionary() {
+SeededNumberDictionary* JSObject::element_dictionary() {
ASSERT(HasDictionaryElements());
- return NumberDictionary::cast(elements());
+ return SeededNumberDictionary::cast(elements());
}
@@ -4328,7 +4331,7 @@ StringHasher::StringHasher(int length, uint32_t seed)
is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
is_first_char_(true),
is_valid_(true) {
- ASSERT(FLAG_randomize_string_hashes || raw_running_hash_ == 0);
+ ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
}
@@ -4535,16 +4538,27 @@ bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
}
-uint32_t NumberDictionaryShape::Hash(uint32_t key) {
- return ComputeIntegerHash(key);
+uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
+ return ComputeIntegerHash(key, 0);
}
-uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
+uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
+ Object* other) {
ASSERT(other->IsNumber());
- return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
+ return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
+}
+
+uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
+ return ComputeIntegerHash(key, seed);
}
+uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
+ uint32_t seed,
+ Object* other) {
+ ASSERT(other->IsNumber());
+ return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
+}
MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
return Isolate::Current()->heap()->NumberFromUint32(key);
diff --git a/deps/v8/src/objects-printer.cc b/deps/v8/src/objects-printer.cc
index 4b5d049f51..e558e583e4 100644
--- a/deps/v8/src/objects-printer.cc
+++ b/deps/v8/src/objects-printer.cc
@@ -786,6 +786,15 @@ void AccessorInfo::AccessorInfoPrint(FILE* out) {
}
+void AccessorPair::AccessorPairPrint(FILE* out) {
+ HeapObject::PrintHeader(out, "AccessorPair");
+ PrintF(out, "\n - getter: ");
+ getter()->ShortPrint(out);
+ PrintF(out, "\n - setter: ");
+ setter()->ShortPrint(out);
+}
+
+
void AccessCheckInfo::AccessCheckInfoPrint(FILE* out) {
HeapObject::PrintHeader(out, "AccessCheckInfo");
PrintF(out, "\n - named_callback: ");
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index 36879099e0..abeeec9e2f 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -246,8 +246,8 @@ MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver,
}
// __defineGetter__ callback
- if (structure->IsFixedArray()) {
- Object* getter = FixedArray::cast(structure)->get(kGetterIndex);
+ if (structure->IsAccessorPair()) {
+ Object* getter = AccessorPair::cast(structure)->getter();
if (getter->IsSpecFunction()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter));
@@ -485,6 +485,16 @@ Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) {
}
+Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyDetails details) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->SetNormalizedProperty(*key, *value, details),
+ Object);
+}
+
+
MaybeObject* JSObject::SetNormalizedProperty(String* name,
Object* value,
PropertyDetails details) {
@@ -1961,6 +1971,17 @@ MaybeObject* JSObject::SetPropertyWithInterceptor(
}
+Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->SetProperty(*key, *value, attributes, strict_mode),
+ Object);
+}
+
+
MaybeObject* JSReceiver::SetProperty(String* name,
Object* value,
PropertyAttributes attributes,
@@ -2018,8 +2039,8 @@ MaybeObject* JSObject::SetPropertyWithCallback(Object* structure,
return *value_handle;
}
- if (structure->IsFixedArray()) {
- Object* setter = FixedArray::cast(structure)->get(kSetterIndex);
+ if (structure->IsAccessorPair()) {
+ Object* setter = AccessorPair::cast(structure)->setter();
if (setter->IsSpecFunction()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return SetPropertyWithDefinedSetter(JSReceiver::cast(setter), value);
@@ -2107,9 +2128,10 @@ MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
if (!JSObject::cast(pt)->HasDictionaryElements()) {
continue;
}
- NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary();
+ SeededNumberDictionary* dictionary =
+ JSObject::cast(pt)->element_dictionary();
int entry = dictionary->FindEntry(index);
- if (entry != NumberDictionary::kNotFound) {
+ if (entry != SeededNumberDictionary::kNotFound) {
PropertyDetails details = dictionary->DetailsAt(entry);
if (details.type() == CALLBACKS) {
*found = true;
@@ -2342,7 +2364,9 @@ Object* Map::GetDescriptorContents(String* sentinel_name,
if (details.type() == ELEMENTS_TRANSITION) {
return descriptors->GetValue(index);
} else {
- *safe_to_add_transition = false;
+ if (safe_to_add_transition != NULL) {
+ *safe_to_add_transition = false;
+ }
}
}
return NULL;
@@ -3024,6 +3048,18 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
// Note that this method cannot be used to set the prototype of a function
// because ConvertDescriptorToField() which is called in "case CALLBACKS:"
// doesn't handle function prototypes correctly.
+Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
+ Handle<JSObject> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyAttributes attributes) {
+ CALL_HEAP_FUNCTION(
+ object->GetIsolate(),
+ object->SetLocalPropertyIgnoreAttributes(*key, *value, attributes),
+ Object);
+}
+
+
MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
String* name,
Object* value,
@@ -3314,6 +3350,15 @@ MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) {
}
+void JSObject::NormalizeProperties(Handle<JSObject> object,
+ PropertyNormalizationMode mode,
+ int expected_additional_properties) {
+ CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
+ object->NormalizeProperties(
+ mode, expected_additional_properties));
+}
+
+
MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
int expected_additional_properties) {
if (!HasFastProperties()) return this;
@@ -3436,6 +3481,14 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
}
+void JSObject::TransformToFastProperties(Handle<JSObject> object,
+ int unused_property_fields) {
+ CALL_HEAP_FUNCTION_VOID(
+ object->GetIsolate(),
+ object->TransformToFastProperties(unused_property_fields));
+}
+
+
MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) {
if (HasFastProperties()) return this;
ASSERT(!IsGlobalObject());
@@ -3444,6 +3497,14 @@ MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) {
}
+Handle<SeededNumberDictionary> JSObject::NormalizeElements(
+ Handle<JSObject> object) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->NormalizeElements(),
+ SeededNumberDictionary);
+}
+
+
MaybeObject* JSObject::NormalizeElements() {
ASSERT(!HasExternalArrayElements());
@@ -3468,11 +3529,11 @@ MaybeObject* JSObject::NormalizeElements() {
int old_capacity = 0;
int used_elements = 0;
GetElementsCapacityAndUsage(&old_capacity, &used_elements);
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
{ Object* object;
- MaybeObject* maybe = NumberDictionary::Allocate(used_elements);
+ MaybeObject* maybe = SeededNumberDictionary::Allocate(used_elements);
if (!maybe->ToObject(&object)) return maybe;
- dictionary = NumberDictionary::cast(object);
+ dictionary = SeededNumberDictionary::cast(object);
}
// Copy the elements to the new backing store.
@@ -3503,7 +3564,7 @@ MaybeObject* JSObject::NormalizeElements() {
MaybeObject* maybe_result =
dictionary->AddNumberEntry(i, value, details);
if (!maybe_result->ToObject(&result)) return maybe_result;
- dictionary = NumberDictionary::cast(result);
+ dictionary = SeededNumberDictionary::cast(result);
}
}
@@ -3560,6 +3621,14 @@ MaybeObject* JSObject::SetIdentityHash(Object* hash, CreationFlag flag) {
}
+int JSObject::GetIdentityHash(Handle<JSObject> obj) {
+ CALL_AND_RETRY(obj->GetIsolate(),
+ obj->GetIdentityHash(ALLOW_CREATION),
+ return Smi::cast(__object__)->value(),
+ return 0);
+}
+
+
MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) {
Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_symbol());
if (stored_value->IsSmi()) return stored_value;
@@ -3612,6 +3681,15 @@ Object* JSObject::GetHiddenProperty(String* key) {
}
+Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj,
+ Handle<String> key,
+ Handle<Object> value) {
+ CALL_HEAP_FUNCTION(obj->GetIsolate(),
+ obj->SetHiddenProperty(*key, *value),
+ Object);
+}
+
+
MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) {
if (IsJSGlobalProxy()) {
// For a proxy, use the prototype as target object.
@@ -3839,6 +3917,14 @@ MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) {
}
+Handle<Object> JSObject::DeleteElement(Handle<JSObject> obj,
+ uint32_t index) {
+ CALL_HEAP_FUNCTION(obj->GetIsolate(),
+ obj->DeleteElement(index, JSObject::NORMAL_DELETION),
+ Object);
+}
+
+
MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
Isolate* isolate = GetIsolate();
// Check access rights if needed.
@@ -3867,19 +3953,11 @@ MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
}
-MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) {
- if (IsJSProxy()) {
- return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode);
- }
- return JSObject::cast(this)->DeleteProperty(name, mode);
-}
-
-
-MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) {
- if (IsJSProxy()) {
- return JSProxy::cast(this)->DeleteElementWithHandler(index, mode);
- }
- return JSObject::cast(this)->DeleteElement(index, mode);
+Handle<Object> JSObject::DeleteProperty(Handle<JSObject> obj,
+ Handle<String> prop) {
+ CALL_HEAP_FUNCTION(obj->GetIsolate(),
+ obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION),
+ Object);
}
@@ -3940,6 +4018,22 @@ MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
}
+MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) {
+ if (IsJSProxy()) {
+ return JSProxy::cast(this)->DeleteElementWithHandler(index, mode);
+ }
+ return JSObject::cast(this)->DeleteElement(index, mode);
+}
+
+
+MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) {
+ if (IsJSProxy()) {
+ return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode);
+ }
+ return JSObject::cast(this)->DeleteProperty(name, mode);
+}
+
+
bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
ElementsKind kind,
Object* object) {
@@ -3954,7 +4048,8 @@ bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
if (!element->IsTheHole() && element == object) return true;
}
} else {
- Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object);
+ Object* key =
+ SeededNumberDictionary::cast(elements)->SlowReverseLookup(object);
if (!key->IsUndefined()) return true;
}
return false;
@@ -4066,6 +4161,11 @@ bool JSObject::ReferencesObject(Object* obj) {
}
+Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(), object->PreventExtensions(), Object);
+}
+
+
MaybeObject* JSObject::PreventExtensions() {
Isolate* isolate = GetIsolate();
if (IsAccessCheckNeeded() &&
@@ -4095,9 +4195,9 @@ MaybeObject* JSObject::PreventExtensions() {
}
// If there are fast elements we normalize.
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
{ MaybeObject* maybe = NormalizeElements();
- if (!maybe->To<NumberDictionary>(&dictionary)) return maybe;
+ if (!maybe->To<SeededNumberDictionary>(&dictionary)) return maybe;
}
ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
// Make sure that we never go back to fast case.
@@ -4257,21 +4357,21 @@ void JSObject::LookupCallback(String* name, LookupResult* result) {
// Search for a getter or setter in an elements dictionary and update its
-// attributes. Returns either undefined if the element is non-deletable, or
-// the getter/setter pair (fixed array) if there is an existing one, or the
-// hole value if the element does not exist or is a normal non-getter/setter
-// data element.
-static Object* UpdateGetterSetterInDictionary(NumberDictionary* dictionary,
- uint32_t index,
- PropertyAttributes attributes,
- Heap* heap) {
+// attributes. Returns either undefined if the element is non-deletable, or the
+// getter/setter pair if there is an existing one, or the hole value if the
+// element does not exist or is a normal non-getter/setter data element.
+static Object* UpdateGetterSetterInDictionary(
+ SeededNumberDictionary* dictionary,
+ uint32_t index,
+ PropertyAttributes attributes,
+ Heap* heap) {
int entry = dictionary->FindEntry(index);
- if (entry != NumberDictionary::kNotFound) {
+ if (entry != SeededNumberDictionary::kNotFound) {
Object* result = dictionary->ValueAt(entry);
PropertyDetails details = dictionary->DetailsAt(entry);
// TODO(mstarzinger): We should check for details.IsDontDelete() here once
// we only call into the runtime once to set both getter and setter.
- if (details.type() == CALLBACKS && result->IsFixedArray()) {
+ if (details.type() == CALLBACKS && result->IsAccessorPair()) {
if (details.attributes() != attributes) {
dictionary->DetailsAtPut(entry,
PropertyDetails(attributes, CALLBACKS, index));
@@ -4338,7 +4438,8 @@ MaybeObject* JSObject::DefineGetterSetter(String* name,
if (probe == NULL || probe->IsTheHole()) {
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
if (arguments->IsDictionary()) {
- NumberDictionary* dictionary = NumberDictionary::cast(arguments);
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(arguments);
probe = UpdateGetterSetterInDictionary(dictionary,
index,
attributes,
@@ -4359,7 +4460,7 @@ MaybeObject* JSObject::DefineGetterSetter(String* name,
if (result.type() == CALLBACKS) {
Object* obj = result.GetCallbackObject();
// Need to preserve old getters/setters.
- if (obj->IsFixedArray()) {
+ if (obj->IsAccessorPair()) {
// Use set to update attributes.
return SetPropertyCallback(name, obj, attributes);
}
@@ -4367,16 +4468,15 @@ MaybeObject* JSObject::DefineGetterSetter(String* name,
}
}
- // Allocate the fixed array to hold getter and setter.
- Object* structure;
- { MaybeObject* maybe_structure = heap->AllocateFixedArray(2, TENURED);
- if (!maybe_structure->ToObject(&structure)) return maybe_structure;
+ AccessorPair* accessors;
+ { MaybeObject* maybe_accessors = heap->AllocateAccessorPair();
+ if (!maybe_accessors->To<AccessorPair>(&accessors)) return maybe_accessors;
}
if (is_element) {
- return SetElementCallback(index, structure, attributes);
+ return SetElementCallback(index, accessors, attributes);
} else {
- return SetPropertyCallback(name, structure, attributes);
+ return SetPropertyCallback(name, accessors, attributes);
}
}
@@ -4411,11 +4511,11 @@ MaybeObject* JSObject::SetElementCallback(uint32_t index,
PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
// Normalize elements to make this operation simple.
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
{ Object* result;
MaybeObject* maybe = NormalizeElements();
if (!maybe->ToObject(&result)) return maybe;
- dictionary = NumberDictionary::cast(result);
+ dictionary = SeededNumberDictionary::cast(result);
}
ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
@@ -4423,7 +4523,7 @@ MaybeObject* JSObject::SetElementCallback(uint32_t index,
{ Object* result;
MaybeObject* maybe = dictionary->Set(index, structure, details);
if (!maybe->ToObject(&result)) return maybe;
- dictionary = NumberDictionary::cast(result);
+ dictionary = SeededNumberDictionary::cast(result);
}
dictionary->set_requires_slow_elements();
@@ -4512,12 +4612,16 @@ MaybeObject* JSObject::DefineAccessor(String* name,
fun, attributes);
}
- Object* array;
- { MaybeObject* maybe_array = DefineGetterSetter(name, attributes);
- if (!maybe_array->ToObject(&array)) return maybe_array;
+ Object* accessors;
+ { MaybeObject* maybe_accessors = DefineGetterSetter(name, attributes);
+ if (!maybe_accessors->To<Object>(&accessors)) return maybe_accessors;
+ }
+ if (accessors->IsUndefined()) return accessors;
+ if (is_getter) {
+ AccessorPair::cast(accessors)->set_getter(fun);
+ } else {
+ AccessorPair::cast(accessors)->set_setter(fun);
}
- if (array->IsUndefined()) return array;
- FixedArray::cast(array)->set(is_getter ? 0 : 1, fun);
return this;
}
@@ -4621,11 +4725,6 @@ Object* JSObject::LookupAccessor(String* name, bool is_getter) {
}
// Make the lookup and include prototypes.
- // Introducing constants below makes static constants usage purely static
- // and avoids linker errors in debug build using gcc.
- const int getter_index = kGetterIndex;
- const int setter_index = kSetterIndex;
- int accessor_index = is_getter ? getter_index : setter_index;
uint32_t index = 0;
if (name->AsArrayIndex(&index)) {
for (Object* obj = this;
@@ -4633,14 +4732,15 @@ Object* JSObject::LookupAccessor(String* name, bool is_getter) {
obj = JSObject::cast(obj)->GetPrototype()) {
JSObject* js_object = JSObject::cast(obj);
if (js_object->HasDictionaryElements()) {
- NumberDictionary* dictionary = js_object->element_dictionary();
+ SeededNumberDictionary* dictionary = js_object->element_dictionary();
int entry = dictionary->FindEntry(index);
- if (entry != NumberDictionary::kNotFound) {
+ if (entry != SeededNumberDictionary::kNotFound) {
Object* element = dictionary->ValueAt(entry);
PropertyDetails details = dictionary->DetailsAt(entry);
if (details.type() == CALLBACKS) {
- if (element->IsFixedArray()) {
- return FixedArray::cast(element)->get(accessor_index);
+ if (element->IsAccessorPair()) {
+ AccessorPair* accessors = AccessorPair::cast(element);
+ return is_getter ? accessors->getter() : accessors->setter();
}
}
}
@@ -4656,8 +4756,9 @@ Object* JSObject::LookupAccessor(String* name, bool is_getter) {
if (result.IsReadOnly()) return heap->undefined_value();
if (result.type() == CALLBACKS) {
Object* obj = result.GetCallbackObject();
- if (obj->IsFixedArray()) {
- return FixedArray::cast(obj)->get(accessor_index);
+ if (obj->IsAccessorPair()) {
+ AccessorPair* accessors = AccessorPair::cast(obj);
+ return is_getter ? accessors->getter() : accessors->setter();
}
}
}
@@ -6833,14 +6934,14 @@ uint32_t String::ComputeAndSetHash() {
if (StringShape(this).IsSequentialAscii()) {
field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(),
len,
- GetHeap()->StringHashSeed());
+ GetHeap()->HashSeed());
} else if (StringShape(this).IsSequentialTwoByte()) {
field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(),
len,
- GetHeap()->StringHashSeed());
+ GetHeap()->HashSeed());
} else {
StringInputBuffer buffer(this);
- field = ComputeHashField(&buffer, len, GetHeap()->StringHashSeed());
+ field = ComputeHashField(&buffer, len, GetHeap()->HashSeed());
}
// Store the hash code in the object.
@@ -8171,7 +8272,7 @@ static void CopyFastElementsToFast(FixedArray* source,
}
-static void CopySlowElementsToFast(NumberDictionary* source,
+static void CopySlowElementsToFast(SeededNumberDictionary* source,
FixedArray* destination,
WriteBarrierMode mode) {
int destination_length = destination->length();
@@ -8237,7 +8338,7 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength(
case DICTIONARY_ELEMENTS: {
AssertNoAllocation no_gc;
WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
- CopySlowElementsToFast(NumberDictionary::cast(old_elements_raw),
+ CopySlowElementsToFast(SeededNumberDictionary::cast(old_elements_raw),
new_elements,
mode);
set_map_and_elements(new_map, new_elements);
@@ -8251,7 +8352,7 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength(
FixedArray* parameter_map = FixedArray::cast(old_elements_raw);
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
if (arguments->IsDictionary()) {
- CopySlowElementsToFast(NumberDictionary::cast(arguments),
+ CopySlowElementsToFast(SeededNumberDictionary::cast(arguments),
new_elements,
mode);
} else {
@@ -8347,7 +8448,7 @@ MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
break;
}
case DICTIONARY_ELEMENTS: {
- elems->Initialize(NumberDictionary::cast(old_elements));
+ elems->Initialize(SeededNumberDictionary::cast(old_elements));
break;
}
default:
@@ -8607,7 +8708,7 @@ bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) {
}
case DICTIONARY_ELEMENTS: {
if (element_dictionary()->FindEntry(index)
- != NumberDictionary::kNotFound) {
+ != SeededNumberDictionary::kNotFound) {
return true;
}
break;
@@ -8745,7 +8846,7 @@ JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) {
}
case DICTIONARY_ELEMENTS: {
if (element_dictionary()->FindEntry(index) !=
- NumberDictionary::kNotFound) {
+ SeededNumberDictionary::kNotFound) {
return DICTIONARY_ELEMENT;
}
break;
@@ -8762,8 +8863,9 @@ JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) {
// If not aliased, check the arguments.
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
if (arguments->IsDictionary()) {
- NumberDictionary* dictionary = NumberDictionary::cast(arguments);
- if (dictionary->FindEntry(index) != NumberDictionary::kNotFound) {
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(arguments);
+ if (dictionary->FindEntry(index) != SeededNumberDictionary::kNotFound) {
return DICTIONARY_ELEMENT;
}
} else {
@@ -8792,8 +8894,8 @@ bool JSObject::HasElementInElements(FixedArray* elements,
return true;
}
} else {
- if (NumberDictionary::cast(elements)->FindEntry(index) !=
- NumberDictionary::kNotFound) {
+ if (SeededNumberDictionary::cast(elements)->FindEntry(index) !=
+ SeededNumberDictionary::kNotFound) {
return true;
}
}
@@ -8860,7 +8962,7 @@ bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
}
case DICTIONARY_ELEMENTS: {
if (element_dictionary()->FindEntry(index)
- != NumberDictionary::kNotFound) {
+ != SeededNumberDictionary::kNotFound) {
return true;
}
break;
@@ -8964,8 +9066,8 @@ MaybeObject* JSObject::GetElementWithCallback(Object* receiver,
}
// __defineGetter__ callback
- if (structure->IsFixedArray()) {
- Object* getter = FixedArray::cast(structure)->get(kGetterIndex);
+ if (structure->IsAccessorPair()) {
+ Object* getter = AccessorPair::cast(structure)->getter();
if (getter->IsSpecFunction()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter));
@@ -9021,8 +9123,8 @@ MaybeObject* JSObject::SetElementWithCallback(Object* structure,
return *value_handle;
}
- if (structure->IsFixedArray()) {
- Handle<Object> setter(FixedArray::cast(structure)->get(kSetterIndex));
+ if (structure->IsAccessorPair()) {
+ Handle<Object> setter(AccessorPair::cast(structure)->setter());
if (setter->IsSpecFunction()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return SetPropertyWithDefinedSetter(JSReceiver::cast(*setter), value);
@@ -9183,15 +9285,15 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
FixedArray* elements = FixedArray::cast(this->elements());
bool is_arguments =
(elements->map() == heap->non_strict_arguments_elements_map());
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
if (is_arguments) {
- dictionary = NumberDictionary::cast(elements->get(1));
+ dictionary = SeededNumberDictionary::cast(elements->get(1));
} else {
- dictionary = NumberDictionary::cast(elements);
+ dictionary = SeededNumberDictionary::cast(elements);
}
int entry = dictionary->FindEntry(index);
- if (entry != NumberDictionary::kNotFound) {
+ if (entry != SeededNumberDictionary::kNotFound) {
Object* element = dictionary->ValueAt(entry);
PropertyDetails details = dictionary->DetailsAt(entry);
if (details.type() == CALLBACKS) {
@@ -9236,13 +9338,13 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
FixedArrayBase* new_dictionary;
MaybeObject* maybe = dictionary->AtNumberPut(index, value);
if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe;
- if (dictionary != NumberDictionary::cast(new_dictionary)) {
+ if (dictionary != SeededNumberDictionary::cast(new_dictionary)) {
if (is_arguments) {
elements->set(1, new_dictionary);
} else {
set_elements(new_dictionary);
}
- dictionary = NumberDictionary::cast(new_dictionary);
+ dictionary = SeededNumberDictionary::cast(new_dictionary);
}
}
@@ -9388,6 +9490,35 @@ MaybeObject* JSReceiver::SetElement(uint32_t index,
}
+Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictModeFlag strict_mode) {
+ ASSERT(!object->HasExternalArrayElements());
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->SetElement(index, *value, strict_mode, false),
+ Object);
+}
+
+
+Handle<Object> JSObject::SetElement(Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictModeFlag strict_mode) {
+ if (object->HasExternalArrayElements()) {
+ if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) {
+ bool has_exception;
+ Handle<Object> number = Execution::ToNumber(value, &has_exception);
+ if (has_exception) return Handle<Object>();
+ value = number;
+ }
+ }
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->SetElement(index, *value, strict_mode, true),
+ Object);
+}
+
+
MaybeObject* JSObject::SetElement(uint32_t index,
Object* value,
StrictModeFlag strict_mode,
@@ -9510,6 +9641,14 @@ MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
}
+Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object,
+ ElementsKind to_kind) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+ object->TransitionElementsKind(to_kind),
+ Object);
+}
+
+
MUST_USE_RESULT MaybeObject* JSObject::TransitionElementsKind(
ElementsKind to_kind) {
ElementsKind from_kind = map()->elements_kind();
@@ -9653,7 +9792,8 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
backing_store = FixedArray::cast(backing_store_base);
if (backing_store->IsDictionary()) {
- NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(backing_store);
*capacity = dictionary->Capacity();
*used = dictionary->NumberOfElements();
break;
@@ -9668,8 +9808,8 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
}
break;
case DICTIONARY_ELEMENTS: {
- NumberDictionary* dictionary =
- NumberDictionary::cast(FixedArray::cast(elements()));
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(FixedArray::cast(elements()));
*capacity = dictionary->Capacity();
*used = dictionary->NumberOfElements();
break;
@@ -9714,8 +9854,8 @@ bool JSObject::ShouldConvertToSlowElements(int new_capacity) {
int old_capacity = 0;
int used_elements = 0;
GetElementsCapacityAndUsage(&old_capacity, &used_elements);
- int dictionary_size = NumberDictionary::ComputeCapacity(used_elements) *
- NumberDictionary::kEntrySize;
+ int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) *
+ SeededNumberDictionary::kEntrySize;
return 3 * dictionary_size <= new_capacity;
}
@@ -9729,11 +9869,11 @@ bool JSObject::ShouldConvertToFastElements() {
if (IsAccessCheckNeeded()) return false;
FixedArray* elements = FixedArray::cast(this->elements());
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) {
- dictionary = NumberDictionary::cast(elements->get(1));
+ dictionary = SeededNumberDictionary::cast(elements->get(1));
} else {
- dictionary = NumberDictionary::cast(elements);
+ dictionary = SeededNumberDictionary::cast(elements);
}
// If an element has been added at a very high index in the elements
// dictionary, we cannot go back to fast case.
@@ -9748,7 +9888,7 @@ bool JSObject::ShouldConvertToFastElements() {
array_size = dictionary->max_number_key();
}
uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
- NumberDictionary::kEntrySize;
+ SeededNumberDictionary::kEntrySize;
return 2 * dictionary_size >= array_size;
}
@@ -9758,7 +9898,8 @@ bool JSObject::ShouldConvertToFastDoubleElements(
*has_smi_only_elements = false;
if (FLAG_unbox_double_arrays) {
ASSERT(HasDictionaryElements());
- NumberDictionary* dictionary = NumberDictionary::cast(elements());
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(elements());
bool found_double = false;
for (int i = 0; i < dictionary->Capacity(); i++) {
Object* key = dictionary->KeyAt(i);
@@ -9978,7 +10119,7 @@ bool JSObject::HasRealElementProperty(uint32_t index) {
}
case DICTIONARY_ELEMENTS: {
return element_dictionary()->FindEntry(index)
- != NumberDictionary::kNotFound;
+ != SeededNumberDictionary::kNotFound;
}
case NON_STRICT_ARGUMENTS_ELEMENTS:
UNIMPLEMENTED();
@@ -10247,7 +10388,7 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
if (storage != NULL) {
element_dictionary()->CopyKeysTo(storage,
filter,
- NumberDictionary::SORTED);
+ SeededNumberDictionary::SORTED);
}
counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
break;
@@ -10259,9 +10400,11 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
if (arguments->IsDictionary()) {
// Copy the keys from arguments first, because Dictionary::CopyKeysTo
// will insert in storage starting at index 0.
- NumberDictionary* dictionary = NumberDictionary::cast(arguments);
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(arguments);
if (storage != NULL) {
- dictionary->CopyKeysTo(storage, filter, NumberDictionary::UNSORTED);
+ dictionary->CopyKeysTo(
+ storage, filter, SeededNumberDictionary::UNSORTED);
}
counter += dictionary->NumberOfElementsFilterAttributes(filter);
for (int i = 0; i < mapped_length; ++i) {
@@ -10585,7 +10728,7 @@ class SubStringAsciiSymbolKey : public HashTableKey {
uint32_t Hash() {
ASSERT(length_ >= 0);
ASSERT(from_ + length_ <= string_->length());
- StringHasher hasher(length_, string_->GetHeap()->StringHashSeed());
+ StringHasher hasher(length_, string_->GetHeap()->HashSeed());
// Very long strings have a trivial hash that doesn't inspect the
// string contents.
@@ -10794,7 +10937,7 @@ MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) {
uint32_t from_index = EntryToIndex(i);
Object* k = get(from_index);
if (IsKey(k)) {
- uint32_t hash = Shape::HashForObject(key, k);
+ uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k);
uint32_t insertion_index =
EntryToIndex(new_table->FindInsertionEntry(hash));
for (int j = 0; j < Shape::kEntrySize; j++) {
@@ -10892,38 +11035,46 @@ template class HashTable<ObjectHashTableShape<2>, Object*>;
template class Dictionary<StringDictionaryShape, String*>;
-template class Dictionary<NumberDictionaryShape, uint32_t>;
+template class Dictionary<SeededNumberDictionaryShape, uint32_t>;
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate(
- int);
+template class Dictionary<UnseededNumberDictionaryShape, uint32_t>;
+
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
+ Allocate(int at_least_space_for);
+
+template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
+ Allocate(int at_least_space_for);
template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate(
int);
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut(
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut(
uint32_t, Object*);
-template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup(
- Object*);
+template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
+ AtPut(uint32_t, Object*);
+
+template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
+ SlowReverseLookup(Object* value);
template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup(
Object*);
-template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo(
+template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo(
FixedArray*,
PropertyAttributes,
- Dictionary<NumberDictionaryShape, uint32_t>::SortMode);
+ Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode);
template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty(
int, JSObject::DeleteMode);
-template Object* Dictionary<NumberDictionaryShape, uint32_t>::DeleteProperty(
- int, JSObject::DeleteMode);
+template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>::
+ DeleteProperty(int, JSObject::DeleteMode);
template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink(
String*);
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink(
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink(
uint32_t);
template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo(
@@ -10942,32 +11093,41 @@ template MaybeObject*
Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices();
template int
-Dictionary<NumberDictionaryShape, uint32_t>::NumberOfElementsFilterAttributes(
- PropertyAttributes);
+Dictionary<SeededNumberDictionaryShape, uint32_t>::
+ NumberOfElementsFilterAttributes(PropertyAttributes);
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Add(
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add(
uint32_t, Object*, PropertyDetails);
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::
+template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add(
+ uint32_t, Object*, PropertyDetails);
+
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
+ EnsureCapacity(int, uint32_t);
+
+template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
EnsureCapacity(int, uint32_t);
template MaybeObject* Dictionary<StringDictionaryShape, String*>::
EnsureCapacity(int, String*);
-template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AddEntry(
- uint32_t, Object*, PropertyDetails, uint32_t);
+template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
+ AddEntry(uint32_t, Object*, PropertyDetails, uint32_t);
+
+template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
+ AddEntry(uint32_t, Object*, PropertyDetails, uint32_t);
template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry(
String*, Object*, PropertyDetails, uint32_t);
template
-int Dictionary<NumberDictionaryShape, uint32_t>::NumberOfEnumElements();
+int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements();
template
int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements();
template
-int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
+int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
// Collates undefined and unexisting elements below limit from position
@@ -10977,7 +11137,7 @@ MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
// Must stay in dictionary mode, either because of requires_slow_elements,
// or because we are not going to sort (and therefore compact) all of the
// elements.
- NumberDictionary* dict = element_dictionary();
+ SeededNumberDictionary* dict = element_dictionary();
HeapNumber* result_double = NULL;
if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
// Allocate space for result before we start mutating the object.
@@ -10990,10 +11150,10 @@ MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
Object* obj;
{ MaybeObject* maybe_obj =
- NumberDictionary::Allocate(dict->NumberOfElements());
+ SeededNumberDictionary::Allocate(dict->NumberOfElements());
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
- NumberDictionary* new_dict = NumberDictionary::cast(obj);
+ SeededNumberDictionary* new_dict = SeededNumberDictionary::cast(obj);
AssertNoAllocation no_alloc;
@@ -11077,7 +11237,7 @@ MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
if (HasDictionaryElements()) {
// Convert to fast elements containing only the existing properties.
// Ordering is irrelevant, since we are going to sort anyway.
- NumberDictionary* dict = element_dictionary();
+ SeededNumberDictionary* dict = element_dictionary();
if (IsJSArray() || dict->requires_slow_elements() ||
dict->max_number_key() >= limit) {
return PrepareSlowElementsForSort(limit);
@@ -11444,7 +11604,7 @@ class TwoCharHashTableKey : public HashTableKey {
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
- if ((hash & String::kHashBitMask) == 0) hash = 27;
+ if ((hash & String::kHashBitMask) == 0) hash = String::kZeroHash;
#ifdef DEBUG
StringHasher hasher(2, seed);
hasher.AddCharacter(c1);
@@ -11503,7 +11663,7 @@ bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) {
bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1,
uint32_t c2,
String** symbol) {
- TwoCharHashTableKey key(c1, c2, GetHeap()->StringHashSeed());
+ TwoCharHashTableKey key(c1, c2, GetHeap()->HashSeed());
int entry = FindEntry(&key);
if (entry == kNotFound) {
return false;
@@ -11518,14 +11678,14 @@ bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1,
MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str,
Object** s) {
- Utf8SymbolKey key(str, GetHeap()->StringHashSeed());
+ Utf8SymbolKey key(str, GetHeap()->HashSeed());
return LookupKey(&key, s);
}
MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str,
Object** s) {
- AsciiSymbolKey key(str, GetHeap()->StringHashSeed());
+ AsciiSymbolKey key(str, GetHeap()->HashSeed());
return LookupKey(&key, s);
}
@@ -11534,14 +11694,14 @@ MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str,
int from,
int length,
Object** s) {
- SubStringAsciiSymbolKey key(str, from, length, GetHeap()->StringHashSeed());
+ SubStringAsciiSymbolKey key(str, from, length, GetHeap()->HashSeed());
return LookupKey(&key, s);
}
MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str,
Object** s) {
- TwoByteSymbolKey key(str, GetHeap()->StringHashSeed());
+ TwoByteSymbolKey key(str, GetHeap()->HashSeed());
return LookupKey(&key, s);
}
@@ -11880,8 +12040,9 @@ MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) {
if (!maybe_k->ToObject(&k)) return maybe_k;
}
PropertyDetails details = PropertyDetails(NONE, NORMAL);
- return Dictionary<Shape, Key>::cast(obj)->
- AddEntry(key, value, details, Shape::Hash(key));
+
+ return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details,
+ Dictionary<Shape, Key>::Hash(key));
}
@@ -11896,8 +12057,9 @@ MaybeObject* Dictionary<Shape, Key>::Add(Key key,
{ MaybeObject* maybe_obj = EnsureCapacity(1, key);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
- return Dictionary<Shape, Key>::cast(obj)->
- AddEntry(key, value, details, Shape::Hash(key));
+
+ return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details,
+ Dictionary<Shape, Key>::Hash(key));
}
@@ -11930,7 +12092,7 @@ MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key,
}
-void NumberDictionary::UpdateMaxNumberKey(uint32_t key) {
+void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) {
// If the dictionary requires slow elements an element has already
// been added at a high index.
if (requires_slow_elements()) return;
@@ -11949,31 +12111,65 @@ void NumberDictionary::UpdateMaxNumberKey(uint32_t key) {
}
-MaybeObject* NumberDictionary::AddNumberEntry(uint32_t key,
- Object* value,
- PropertyDetails details) {
+MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key,
+ Object* value,
+ PropertyDetails details) {
UpdateMaxNumberKey(key);
SLOW_ASSERT(this->FindEntry(key) == kNotFound);
return Add(key, value, details);
}
-MaybeObject* NumberDictionary::AtNumberPut(uint32_t key, Object* value) {
+MaybeObject* UnseededNumberDictionary::AddNumberEntry(uint32_t key,
+ Object* value) {
+ SLOW_ASSERT(this->FindEntry(key) == kNotFound);
+ return Add(key, value, PropertyDetails(NONE, NORMAL));
+}
+
+
+MaybeObject* SeededNumberDictionary::AtNumberPut(uint32_t key, Object* value) {
UpdateMaxNumberKey(key);
return AtPut(key, value);
}
-MaybeObject* NumberDictionary::Set(uint32_t key,
- Object* value,
- PropertyDetails details) {
+MaybeObject* UnseededNumberDictionary::AtNumberPut(uint32_t key,
+ Object* value) {
+ return AtPut(key, value);
+}
+
+
+Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
+ Handle<SeededNumberDictionary> dictionary,
+ uint32_t index,
+ Handle<Object> value,
+ PropertyDetails details) {
+ CALL_HEAP_FUNCTION(dictionary->GetIsolate(),
+ dictionary->Set(index, *value, details),
+ SeededNumberDictionary);
+}
+
+
+Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
+ Handle<UnseededNumberDictionary> dictionary,
+ uint32_t index,
+ Handle<Object> value) {
+ CALL_HEAP_FUNCTION(dictionary->GetIsolate(),
+ dictionary->Set(index, *value),
+ UnseededNumberDictionary);
+}
+
+
+MaybeObject* SeededNumberDictionary::Set(uint32_t key,
+ Object* value,
+ PropertyDetails details) {
int entry = FindEntry(key);
if (entry == kNotFound) return AddNumberEntry(key, value, details);
// Preserve enumeration index.
details = PropertyDetails(details.attributes(),
details.type(),
DetailsAt(entry).index());
- MaybeObject* maybe_object_key = NumberDictionaryShape::AsObject(key);
+ MaybeObject* maybe_object_key = SeededNumberDictionaryShape::AsObject(key);
Object* object_key;
if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
SetEntry(entry, object_key, value, details);
@@ -11981,6 +12177,18 @@ MaybeObject* NumberDictionary::Set(uint32_t key,
}
+MaybeObject* UnseededNumberDictionary::Set(uint32_t key,
+ Object* value) {
+ int entry = FindEntry(key);
+ if (entry == kNotFound) return AddNumberEntry(key, value);
+ MaybeObject* maybe_object_key = UnseededNumberDictionaryShape::AsObject(key);
+ Object* object_key;
+ if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
+ SetEntry(entry, object_key, value);
+ return this;
+}
+
+
template<typename Shape, typename Key>
int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes(
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index 541334a5dc..791aeb3647 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -107,6 +107,7 @@
// - SharedFunctionInfo
// - Struct
// - AccessorInfo
+// - AccessorPair
// - AccessCheckInfo
// - InterceptorInfo
// - CallHandlerInfo
@@ -162,6 +163,11 @@ enum ElementsKind {
LAST_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS
};
+enum CompareMapMode {
+ REQUIRE_EXACT_MAP,
+ ALLOW_ELEMENT_TRANSITION_MAPS
+};
+
const int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1;
void PrintElementsKind(FILE* out, ElementsKind kind);
@@ -270,6 +276,7 @@ const int kVariableSizeSentinel = 0;
V(FILLER_TYPE) \
\
V(ACCESSOR_INFO_TYPE) \
+ V(ACCESSOR_PAIR_TYPE) \
V(ACCESS_CHECK_INFO_TYPE) \
V(INTERCEPTOR_INFO_TYPE) \
V(CALL_HANDLER_INFO_TYPE) \
@@ -417,6 +424,7 @@ const int kVariableSizeSentinel = 0;
// manually.
#define STRUCT_LIST_ALL(V) \
V(ACCESSOR_INFO, AccessorInfo, accessor_info) \
+ V(ACCESSOR_PAIR, AccessorPair, accessor_pair) \
V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \
V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \
V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info) \
@@ -570,6 +578,7 @@ enum InstanceType {
// Structs.
ACCESSOR_INFO_TYPE,
+ ACCESSOR_PAIR_TYPE,
ACCESS_CHECK_INFO_TYPE,
INTERCEPTOR_INFO_TYPE,
CALL_HANDLER_INFO_TYPE,
@@ -1342,6 +1351,11 @@ class JSReceiver: public HeapObject {
// Casting.
static inline JSReceiver* cast(Object* obj);
+ static Handle<Object> SetProperty(Handle<JSReceiver> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode);
// Can cause GC.
MUST_USE_RESULT MaybeObject* SetProperty(String* key,
Object* value,
@@ -1471,7 +1485,7 @@ class JSObject: public JSReceiver {
inline bool HasExternalDoubleElements();
bool HasFastArgumentsElements();
bool HasDictionaryArgumentsElements();
- inline NumberDictionary* element_dictionary(); // Gets slow elements.
+ inline SeededNumberDictionary* element_dictionary(); // Gets slow elements.
inline void set_map_and_elements(
Map* map,
@@ -1521,6 +1535,14 @@ class JSObject: public JSReceiver {
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
+
+ static Handle<Object> SetLocalPropertyIgnoreAttributes(
+ Handle<JSObject> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyAttributes attributes);
+
+ // Can cause GC.
MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
String* key,
Object* value,
@@ -1536,6 +1558,11 @@ class JSObject: public JSReceiver {
// Sets the property value in a normalized object given (key, value, details).
// Handles the special representation of JS global objects.
+ static Handle<Object> SetNormalizedProperty(Handle<JSObject> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyDetails details);
+
MUST_USE_RESULT MaybeObject* SetNormalizedProperty(String* name,
Object* value,
PropertyDetails details);
@@ -1605,8 +1632,11 @@ class JSObject: public JSReceiver {
// hidden properties.
// Sets a hidden property on this object. Returns this object if successful,
- // undefined if called on a detached proxy, and a failure if a GC
- // is required
+ // undefined if called on a detached proxy.
+ static Handle<Object> SetHiddenProperty(Handle<JSObject> obj,
+ Handle<String> key,
+ Handle<Object> value);
+ // Returns a failure if a GC is required.
MaybeObject* SetHiddenProperty(String* key, Object* value);
// Gets the value of a hidden property with the given key. Returns undefined
// if the property doesn't exist (or if called on a detached proxy),
@@ -1618,10 +1648,15 @@ class JSObject: public JSReceiver {
// Returns true if the object has a property with the hidden symbol as name.
bool HasHiddenProperties();
+ static int GetIdentityHash(Handle<JSObject> obj);
MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
MUST_USE_RESULT MaybeObject* SetIdentityHash(Object* hash, CreationFlag flag);
+ static Handle<Object> DeleteProperty(Handle<JSObject> obj,
+ Handle<String> name);
MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode);
+
+ static Handle<Object> DeleteElement(Handle<JSObject> obj, uint32_t index);
MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode);
inline void ValidateSmiOnlyElements();
@@ -1701,7 +1736,18 @@ class JSObject: public JSReceiver {
StrictModeFlag strict_mode,
bool check_prototype = true);
- // Set the index'th array element.
+
+ static Handle<Object> SetOwnElement(Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictModeFlag strict_mode);
+
+ // Empty handle is returned if the element cannot be set to the given value.
+ static MUST_USE_RESULT Handle<Object> SetElement(Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictModeFlag strict_mode);
+
// A Failure object is returned if GC is needed.
MUST_USE_RESULT MaybeObject* SetElement(uint32_t index,
Object* value,
@@ -1811,6 +1857,9 @@ class JSObject: public JSReceiver {
MUST_USE_RESULT MaybeObject* GetElementsTransitionMap(
ElementsKind elements_kind);
+ static Handle<Object> TransitionElementsKind(Handle<JSObject> object,
+ ElementsKind to_kind);
+
MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
// Converts a descriptor of any other type to a real field,
@@ -1851,12 +1900,19 @@ class JSObject: public JSReceiver {
// representation. If the object is expected to have additional properties
// added this number can be indicated to have the backing store allocated to
// an initial capacity for holding these properties.
+ static void NormalizeProperties(Handle<JSObject> object,
+ PropertyNormalizationMode mode,
+ int expected_additional_properties);
+
MUST_USE_RESULT MaybeObject* NormalizeProperties(
PropertyNormalizationMode mode,
int expected_additional_properties);
- // Convert and update the elements backing store to be a NumberDictionary
- // dictionary. Returns the backing after conversion.
+ // Convert and update the elements backing store to be a
+ // SeededNumberDictionary dictionary. Returns the backing after conversion.
+ static Handle<SeededNumberDictionary> NormalizeElements(
+ Handle<JSObject> object);
+
MUST_USE_RESULT MaybeObject* NormalizeElements();
static void UpdateMapCodeCache(Handle<JSObject> object,
@@ -1867,6 +1923,9 @@ class JSObject: public JSReceiver {
// Transform slow named properties to fast variants.
// Returns failure if allocation failed.
+ static void TransformToFastProperties(Handle<JSObject> object,
+ int unused_property_fields);
+
MUST_USE_RESULT MaybeObject* TransformToFastProperties(
int unused_property_fields);
@@ -1898,6 +1957,7 @@ class JSObject: public JSReceiver {
static inline JSObject* cast(Object* obj);
// Disalow further properties to be added to the object.
+ static Handle<Object> PreventExtensions(Handle<JSObject> object);
MUST_USE_RESULT MaybeObject* PreventExtensions();
@@ -1951,11 +2011,6 @@ class JSObject: public JSReceiver {
#endif
Object* SlowReverseLookup(Object* value);
- // Getters and setters are stored in a fixed array property.
- // These are constants for their indices.
- static const int kGetterIndex = 0;
- static const int kSetterIndex = 1;
-
// Maximal number of fast properties for the JSObject. Used to
// restrict the number of map transitions to avoid an explosion in
// the number of maps for objects used as dictionaries.
@@ -2223,7 +2278,7 @@ class FixedDoubleArray: public FixedArrayBase {
public:
inline void Initialize(FixedArray* from);
inline void Initialize(FixedDoubleArray* from);
- inline void Initialize(NumberDictionary* from);
+ inline void Initialize(SeededNumberDictionary* from);
// Setter and getter for elements.
inline double get_scalar(int index);
@@ -2538,9 +2593,44 @@ class DescriptorArray: public FixedArray {
// beginning of the backing storage that can be used for non-element
// information by subclasses.
+template<typename Key>
+class BaseShape {
+ public:
+ static const bool UsesSeed = false;
+ static uint32_t Hash(Key key) { return 0; }
+ static uint32_t SeededHash(Key key, uint32_t seed) {
+ ASSERT(UsesSeed);
+ return Hash(key);
+ }
+ static uint32_t HashForObject(Key key, Object* object) { return 0; }
+ static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
+ ASSERT(UsesSeed);
+ return HashForObject(key, object);
+ }
+};
+
template<typename Shape, typename Key>
class HashTable: public FixedArray {
public:
+ // Wrapper methods
+ inline uint32_t Hash(Key key) {
+ if (Shape::UsesSeed) {
+ return Shape::SeededHash(key,
+ GetHeap()->HashSeed());
+ } else {
+ return Shape::Hash(key);
+ }
+ }
+
+ inline uint32_t HashForObject(Key key, Object* object) {
+ if (Shape::UsesSeed) {
+ return Shape::SeededHashForObject(key,
+ GetHeap()->HashSeed(), object);
+ } else {
+ return Shape::HashForObject(key, object);
+ }
+ }
+
// Returns the number of elements in the hash table.
int NumberOfElements() {
return Smi::cast(get(kNumberOfElementsIndex))->value();
@@ -2682,7 +2772,6 @@ class HashTable: public FixedArray {
};
-
// HashTableKey is an abstract superclass for virtual key behavior.
class HashTableKey {
public:
@@ -2699,7 +2788,8 @@ class HashTableKey {
virtual ~HashTableKey() {}
};
-class SymbolTableShape {
+
+class SymbolTableShape : public BaseShape<HashTableKey*> {
public:
static inline bool IsMatch(HashTableKey* key, Object* value) {
return key->IsMatch(value);
@@ -2758,7 +2848,7 @@ class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> {
};
-class MapCacheShape {
+class MapCacheShape : public BaseShape<HashTableKey*> {
public:
static inline bool IsMatch(HashTableKey* key, Object* value) {
return key->IsMatch(value);
@@ -2914,7 +3004,7 @@ class Dictionary: public HashTable<Shape, Key> {
};
-class StringDictionaryShape {
+class StringDictionaryShape : public BaseShape<String*> {
public:
static inline bool IsMatch(String* key, Object* other);
static inline uint32_t Hash(String* key);
@@ -2947,23 +3037,42 @@ class StringDictionary: public Dictionary<StringDictionaryShape, String*> {
};
-class NumberDictionaryShape {
+class NumberDictionaryShape : public BaseShape<uint32_t> {
public:
static inline bool IsMatch(uint32_t key, Object* other);
- static inline uint32_t Hash(uint32_t key);
- static inline uint32_t HashForObject(uint32_t key, Object* object);
MUST_USE_RESULT static inline MaybeObject* AsObject(uint32_t key);
- static const int kPrefixSize = 2;
static const int kEntrySize = 3;
static const bool kIsEnumerable = false;
};
-class NumberDictionary: public Dictionary<NumberDictionaryShape, uint32_t> {
+class SeededNumberDictionaryShape : public NumberDictionaryShape {
+ public:
+ static const bool UsesSeed = true;
+ static const int kPrefixSize = 2;
+
+ static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
+ static inline uint32_t SeededHashForObject(uint32_t key,
+ uint32_t seed,
+ Object* object);
+};
+
+
+class UnseededNumberDictionaryShape : public NumberDictionaryShape {
public:
- static NumberDictionary* cast(Object* obj) {
+ static const int kPrefixSize = 0;
+
+ static inline uint32_t Hash(uint32_t key);
+ static inline uint32_t HashForObject(uint32_t key, Object* object);
+};
+
+
+class SeededNumberDictionary
+ : public Dictionary<SeededNumberDictionaryShape, uint32_t> {
+ public:
+ static SeededNumberDictionary* cast(Object* obj) {
ASSERT(obj->IsDictionary());
- return reinterpret_cast<NumberDictionary*>(obj);
+ return reinterpret_cast<SeededNumberDictionary*>(obj);
}
// Type specific at put (default NONE attributes is used when adding).
@@ -2973,6 +3082,13 @@ class NumberDictionary: public Dictionary<NumberDictionaryShape, uint32_t> {
PropertyDetails details);
// Set an existing entry or add a new one if needed.
+ // Return the updated dictionary.
+ MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
+ Handle<SeededNumberDictionary> dictionary,
+ uint32_t index,
+ Handle<Object> value,
+ PropertyDetails details);
+
MUST_USE_RESULT MaybeObject* Set(uint32_t key,
Object* value,
PropertyDetails details);
@@ -2999,8 +3115,31 @@ class NumberDictionary: public Dictionary<NumberDictionaryShape, uint32_t> {
};
+class UnseededNumberDictionary
+ : public Dictionary<UnseededNumberDictionaryShape, uint32_t> {
+ public:
+ static UnseededNumberDictionary* cast(Object* obj) {
+ ASSERT(obj->IsDictionary());
+ return reinterpret_cast<UnseededNumberDictionary*>(obj);
+ }
+
+ // Type specific at put (default NONE attributes is used when adding).
+ MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
+ MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key, Object* value);
+
+ // Set an existing entry or add a new one if needed.
+ // Return the updated dictionary.
+ MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
+ Handle<UnseededNumberDictionary> dictionary,
+ uint32_t index,
+ Handle<Object> value);
+
+ MUST_USE_RESULT MaybeObject* Set(uint32_t key, Object* value);
+};
+
+
template <int entrysize>
-class ObjectHashTableShape {
+class ObjectHashTableShape : public BaseShape<Object*> {
public:
static inline bool IsMatch(Object* key, Object* other);
static inline uint32_t Hash(Object* key);
@@ -4791,7 +4930,10 @@ class Script: public Struct {
V(Math, atan, MathATan) \
V(Math, exp, MathExp) \
V(Math, sqrt, MathSqrt) \
- V(Math, pow, MathPow)
+ V(Math, pow, MathPow) \
+ V(Math, random, MathRandom) \
+ V(Math, max, MathMax) \
+ V(Math, min, MathMin)
enum BuiltinFunctionId {
@@ -5912,7 +6054,7 @@ class JSRegExp: public JSObject {
};
-class CompilationCacheShape {
+class CompilationCacheShape : public BaseShape<HashTableKey*> {
public:
static inline bool IsMatch(HashTableKey* key, Object* value) {
return key->IsMatch(value);
@@ -6016,7 +6158,7 @@ class CodeCache: public Struct {
};
-class CodeCacheHashTableShape {
+class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
public:
static inline bool IsMatch(HashTableKey* key, Object* value) {
return key->IsMatch(value);
@@ -6148,6 +6290,11 @@ class StringHasher {
// value is represented decimal value.
static uint32_t MakeArrayIndexHash(uint32_t value, int length);
+ // No string is allowed to have a hash of zero. That value is reserved
+ // for internal properties. If the hash calculation yields zero then we
+ // use 27 instead.
+ static const int kZeroHash = 27;
+
private:
uint32_t array_index() {
ASSERT(is_array_index());
@@ -7528,6 +7675,35 @@ class AccessorInfo: public Struct {
};
+// Support for JavaScript accessors: A pair of a getter and a setter. Each
+// accessor can either be
+// * a pointer to a JavaScript function or proxy: a real accessor
+// * undefined: considered an accessor by the spec, too, strangely enough
+// * the hole: an accessor which has not been set
+// * a pointer to a map: a transition used to ensure map sharing
+class AccessorPair: public Struct {
+ public:
+ DECL_ACCESSORS(getter, Object)
+ DECL_ACCESSORS(setter, Object)
+
+ static inline AccessorPair* cast(Object* obj);
+
+#ifdef OBJECT_PRINT
+ void AccessorPairPrint(FILE* out = stdout);
+#endif
+#ifdef DEBUG
+ void AccessorPairVerify();
+#endif
+
+ static const int kGetterOffset = HeapObject::kHeaderSize;
+ static const int kSetterOffset = kGetterOffset + kPointerSize;
+ static const int kSize = kSetterOffset + kPointerSize;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
+};
+
+
class AccessCheckInfo: public Struct {
public:
DECL_ACCESSORS(named_callback, Object)
diff --git a/deps/v8/src/parser.cc b/deps/v8/src/parser.cc
index c1681cfbd0..777436ee04 100644
--- a/deps/v8/src/parser.cc
+++ b/deps/v8/src/parser.cc
@@ -1186,8 +1186,8 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
if (directive_prologue) {
// A shot at a directive.
- ExpressionStatement *e_stat;
- Literal *literal;
+ ExpressionStatement* e_stat;
+ Literal* literal;
// Still processing directive prologue?
if ((e_stat = stat->AsExpressionStatement()) != NULL &&
(literal = e_stat->expression()->AsLiteral()) != NULL &&
@@ -1562,7 +1562,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
// TODO(1240846): It's weird that native function declarations are
// introduced dynamically when we meet their declarations, whereas
- // other functions are setup when entering the surrounding scope.
+ // other functions are set up when entering the surrounding scope.
SharedFunctionInfoLiteral* lit =
new(zone()) SharedFunctionInfoLiteral(isolate(), shared);
VariableProxy* var = Declare(name, VAR, NULL, true, CHECK_OK);
@@ -3003,7 +3003,19 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
}
case Token::LPAREN: {
- int pos = scanner().location().beg_pos;
+ int pos;
+ if (scanner().current_token() == Token::IDENTIFIER) {
+ // For call of an identifier we want to report position of
+ // the identifier as position of the call in the stack trace.
+ pos = scanner().location().beg_pos;
+ } else {
+ // For other kinds of calls we record position of the parenthesis as
+ // position of the call. Note that this is extremely important for
+ // expressions of the form function(){...}() for which call position
+ // should not point to the closing brace otherwise it will intersect
+ // with positions recorded for function literal and confuse debugger.
+ pos = scanner().peek_location().beg_pos;
+ }
ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
// Keep track of eval() calls since they disable all local variable
@@ -3595,7 +3607,7 @@ void ObjectLiteralPropertyChecker::CheckProperty(
ASSERT(property != NULL);
- Literal *lit = property->key();
+ Literal* lit = property->key();
Handle<Object> handle = lit->handle();
uint32_t hash;
diff --git a/deps/v8/src/platform-cygwin.cc b/deps/v8/src/platform-cygwin.cc
index a72f5da4b7..9b34de91ce 100644
--- a/deps/v8/src/platform-cygwin.cc
+++ b/deps/v8/src/platform-cygwin.cc
@@ -61,7 +61,7 @@ double ceiling(double x) {
static Mutex* limit_mutex = NULL;
-void OS::Setup() {
+void OS::SetUp() {
// Seed the random number generator.
// Convert the current time to a 64-bit integer first, before converting it
// to an unsigned. Going directly can cause an overflow and the seed to be
@@ -290,7 +290,7 @@ void OS::LogSharedLibraryAddresses() {
}
LOG(isolate, SharedLibraryEvent(lib_name, start, end));
} else {
- // Entry not describing executable data. Skip to end of line to setup
+ // Entry not describing executable data. Skip to end of line to set up
// reading the next entry.
do {
c = getc(fp);
diff --git a/deps/v8/src/platform-freebsd.cc b/deps/v8/src/platform-freebsd.cc
index 20bd837931..7d0d8d026d 100644
--- a/deps/v8/src/platform-freebsd.cc
+++ b/deps/v8/src/platform-freebsd.cc
@@ -79,7 +79,7 @@ double ceiling(double x) {
static Mutex* limit_mutex = NULL;
-void OS::Setup() {
+void OS::SetUp() {
// Seed the random number generator.
// Convert the current time to a 64-bit integer first, before converting it
// to an unsigned. Going directly can cause an overflow and the seed to be
diff --git a/deps/v8/src/platform-linux.cc b/deps/v8/src/platform-linux.cc
index e72d095b0a..a3cdc031ef 100644
--- a/deps/v8/src/platform-linux.cc
+++ b/deps/v8/src/platform-linux.cc
@@ -78,7 +78,7 @@ double ceiling(double x) {
static Mutex* limit_mutex = NULL;
-void OS::Setup() {
+void OS::SetUp() {
// Seed the random number generator. We preserve microsecond resolution.
uint64_t seed = Ticks() ^ (getpid() << 16);
srandom(static_cast<unsigned int>(seed));
@@ -512,7 +512,7 @@ void OS::LogSharedLibraryAddresses() {
}
LOG(isolate, SharedLibraryEvent(lib_name, start, end));
} else {
- // Entry not describing executable data. Skip to end of line to setup
+ // Entry not describing executable data. Skip to end of line to set up
// reading the next entry.
do {
c = getc(fp);
diff --git a/deps/v8/src/platform-macos.cc b/deps/v8/src/platform-macos.cc
index 6e5d29da2f..417fb11ae1 100644
--- a/deps/v8/src/platform-macos.cc
+++ b/deps/v8/src/platform-macos.cc
@@ -93,7 +93,7 @@ double ceiling(double x) {
static Mutex* limit_mutex = NULL;
-void OS::Setup() {
+void OS::SetUp() {
// Seed the random number generator. We preserve microsecond resolution.
uint64_t seed = Ticks() ^ (getpid() << 16);
srandom(static_cast<unsigned int>(seed));
diff --git a/deps/v8/src/platform-nullos.cc b/deps/v8/src/platform-nullos.cc
index 8c2a8633d7..094f950f72 100644
--- a/deps/v8/src/platform-nullos.cc
+++ b/deps/v8/src/platform-nullos.cc
@@ -56,7 +56,7 @@ double modulo(double x, double y) {
// Initialize OS class early in the V8 startup.
-void OS::Setup() {
+void OS::SetUp() {
// Seed the random number generator.
UNIMPLEMENTED();
}
diff --git a/deps/v8/src/platform-openbsd.cc b/deps/v8/src/platform-openbsd.cc
index 772d08b587..6f582d4341 100644
--- a/deps/v8/src/platform-openbsd.cc
+++ b/deps/v8/src/platform-openbsd.cc
@@ -99,7 +99,7 @@ static void* GetRandomMmapAddr() {
}
-void OS::Setup() {
+void OS::SetUp() {
// Seed the random number generator. We preserve microsecond resolution.
uint64_t seed = Ticks() ^ (getpid() << 16);
srandom(static_cast<unsigned int>(seed));
@@ -312,7 +312,7 @@ void OS::LogSharedLibraryAddresses() {
}
LOG(isolate, SharedLibraryEvent(lib_name, start, end));
} else {
- // Entry not describing executable data. Skip to end of line to setup
+ // Entry not describing executable data. Skip to end of line to set up
// reading the next entry.
do {
c = getc(fp);
diff --git a/deps/v8/src/platform-posix.cc b/deps/v8/src/platform-posix.cc
index 08417ff9bc..34fd5c4498 100644
--- a/deps/v8/src/platform-posix.cc
+++ b/deps/v8/src/platform-posix.cc
@@ -461,7 +461,7 @@ bool POSIXSocket::SetReuseAddress(bool reuse_address) {
}
-bool Socket::Setup() {
+bool Socket::SetUp() {
// Nothing to do on POSIX.
return true;
}
diff --git a/deps/v8/src/platform-solaris.cc b/deps/v8/src/platform-solaris.cc
index 035d394453..d55ea8913b 100644
--- a/deps/v8/src/platform-solaris.cc
+++ b/deps/v8/src/platform-solaris.cc
@@ -89,7 +89,7 @@ double ceiling(double x) {
static Mutex* limit_mutex = NULL;
-void OS::Setup() {
+void OS::SetUp() {
// Seed the random number generator.
// Convert the current time to a 64-bit integer first, before converting it
// to an unsigned. Going directly will cause an overflow and the seed to be
diff --git a/deps/v8/src/platform-win32.cc b/deps/v8/src/platform-win32.cc
index 822f360642..c439ab91a0 100644
--- a/deps/v8/src/platform-win32.cc
+++ b/deps/v8/src/platform-win32.cc
@@ -528,7 +528,7 @@ char* Time::LocalTimezone() {
}
-void OS::Setup() {
+void OS::SetUp() {
// Seed the random number generator.
// Convert the current time to a 64-bit integer first, before converting it
// to an unsigned. Going directly can cause an overflow and the seed to be
@@ -1825,7 +1825,7 @@ bool Win32Socket::SetReuseAddress(bool reuse_address) {
}
-bool Socket::Setup() {
+bool Socket::SetUp() {
// Initialize Winsock32
int err;
WSADATA winsock_data;
diff --git a/deps/v8/src/platform.h b/deps/v8/src/platform.h
index 127f788f9d..fc12df2d7c 100644
--- a/deps/v8/src/platform.h
+++ b/deps/v8/src/platform.h
@@ -109,7 +109,7 @@ class Socket;
class OS {
public:
// Initializes the platform OS support. Called once at VM startup.
- static void Setup();
+ static void SetUp();
// Returns the accumulated user time for thread. This routine
// can be used for profiling. The implementation should
@@ -477,7 +477,7 @@ class Thread {
PlatformData* data() { return data_; }
private:
- void set_name(const char *name);
+ void set_name(const char* name);
PlatformData* data_;
@@ -553,7 +553,7 @@ class Semaphore {
virtual void Wait() = 0;
// Suspends the calling thread until the counter is non zero or the timeout
- // time has passsed. If timeout happens the return value is false and the
+ // time has passed. If timeout happens the return value is false and the
// counter is unchanged. Otherwise the semaphore counter is decremented and
// true is returned. The timeout value is specified in microseconds.
virtual bool Wait(int timeout) = 0;
@@ -593,7 +593,7 @@ class Socket {
virtual bool IsValid() const = 0;
- static bool Setup();
+ static bool SetUp();
static int LastError();
static uint16_t HToN(uint16_t value);
static uint16_t NToH(uint16_t value);
diff --git a/deps/v8/src/preparser.h b/deps/v8/src/preparser.h
index fc8a4a0ca8..f17bac2eac 100644
--- a/deps/v8/src/preparser.h
+++ b/deps/v8/src/preparser.h
@@ -630,7 +630,7 @@ class PreParser {
void SetStrictModeViolation(i::Scanner::Location,
const char* type,
- bool *ok);
+ bool* ok);
void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok);
diff --git a/deps/v8/src/profile-generator.cc b/deps/v8/src/profile-generator.cc
index 00fc7b736a..97de08e5bf 100644
--- a/deps/v8/src/profile-generator.cc
+++ b/deps/v8/src/profile-generator.cc
@@ -111,7 +111,7 @@ const char* StringsStorage::GetCopy(const char* src) {
OS::StrNCpy(dst, src, len);
dst[len] = '\0';
uint32_t hash =
- HashSequentialString(dst.start(), len, HEAP->StringHashSeed());
+ HashSequentialString(dst.start(), len, HEAP->HashSeed());
return AddOrDisposeString(dst.start(), hash);
}
@@ -145,7 +145,7 @@ const char* StringsStorage::GetVFormatted(const char* format, va_list args) {
return format;
}
uint32_t hash = HashSequentialString(
- str.start(), len, HEAP->StringHashSeed());
+ str.start(), len, HEAP->HashSeed());
return AddOrDisposeString(str.start(), hash);
}
@@ -156,7 +156,7 @@ const char* StringsStorage::GetName(String* name) {
SmartArrayPointer<char> data =
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, 0, length);
uint32_t hash =
- HashSequentialString(*data, length, name->GetHeap()->StringHashSeed());
+ HashSequentialString(*data, length, name->GetHeap()->HashSeed());
return AddOrDisposeString(data.Detach(), hash);
}
return "";
@@ -181,18 +181,21 @@ void CodeEntry::CopyData(const CodeEntry& source) {
uint32_t CodeEntry::GetCallUid() const {
- uint32_t hash = ComputeIntegerHash(tag_);
+ uint32_t hash = ComputeIntegerHash(tag_, v8::internal::kZeroHashSeed);
if (shared_id_ != 0) {
- hash ^= ComputeIntegerHash(
- static_cast<uint32_t>(shared_id_));
+ hash ^= ComputeIntegerHash(static_cast<uint32_t>(shared_id_),
+ v8::internal::kZeroHashSeed);
} else {
hash ^= ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_prefix_)));
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_prefix_)),
+ v8::internal::kZeroHashSeed);
hash ^= ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_)));
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_)),
+ v8::internal::kZeroHashSeed);
hash ^= ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(resource_name_)));
- hash ^= ComputeIntegerHash(line_number_);
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(resource_name_)),
+ v8::internal::kZeroHashSeed);
+ hash ^= ComputeIntegerHash(line_number_, v8::internal::kZeroHashSeed);
}
return hash;
}
@@ -901,7 +904,7 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
entry++;
}
- for (const Address *stack_pos = sample.stack,
+ for (const Address* stack_pos = sample.stack,
*stack_end = stack_pos + sample.frames_count;
stack_pos != stack_end;
++stack_pos) {
@@ -1228,10 +1231,10 @@ HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection,
entries_sorted_(false) {
STATIC_ASSERT(
sizeof(HeapGraphEdge) ==
- SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapGraphEdgeSize); // NOLINT
+ SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize);
STATIC_ASSERT(
sizeof(HeapEntry) ==
- SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapEntrySize); // NOLINT
+ SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize);
for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) {
gc_subroot_entries_[i] = NULL;
}
@@ -1506,10 +1509,11 @@ uint64_t HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) {
const char* label = info->GetLabel();
id ^= HashSequentialString(label,
static_cast<int>(strlen(label)),
- HEAP->StringHashSeed());
+ HEAP->HashSeed());
intptr_t element_count = info->GetElementCount();
if (element_count != -1)
- id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count));
+ id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count),
+ v8::internal::kZeroHashSeed);
return id << 1;
}
@@ -1591,7 +1595,7 @@ Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById(uint64_t id) {
}
-HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder =
+HeapEntry* const HeapEntriesMap::kHeapEntryPlaceholder =
reinterpret_cast<HeapEntry*>(1);
HeapEntriesMap::HeapEntriesMap()
@@ -1720,16 +1724,16 @@ void HeapObjectsSet::SetTag(Object* obj, const char* tag) {
}
-HeapObject *const V8HeapExplorer::kInternalRootObject =
+HeapObject* const V8HeapExplorer::kInternalRootObject =
reinterpret_cast<HeapObject*>(
static_cast<intptr_t>(HeapObjectsMap::kInternalRootObjectId));
-HeapObject *const V8HeapExplorer::kGcRootsObject =
+HeapObject* const V8HeapExplorer::kGcRootsObject =
reinterpret_cast<HeapObject*>(
static_cast<intptr_t>(HeapObjectsMap::kGcRootsObjectId));
-HeapObject *const V8HeapExplorer::kFirstGcSubrootObject =
+HeapObject* const V8HeapExplorer::kFirstGcSubrootObject =
reinterpret_cast<HeapObject*>(
static_cast<intptr_t>(HeapObjectsMap::kGcRootsFirstSubrootId));
-HeapObject *const V8HeapExplorer::kLastGcSubrootObject =
+HeapObject* const V8HeapExplorer::kLastGcSubrootObject =
reinterpret_cast<HeapObject*>(
static_cast<intptr_t>(HeapObjectsMap::kFirstAvailableObjectId));
@@ -2226,13 +2230,13 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj,
break;
case CALLBACKS: {
Object* callback_obj = descs->GetValue(i);
- if (callback_obj->IsFixedArray()) {
- FixedArray* accessors = FixedArray::cast(callback_obj);
- if (Object* getter = accessors->get(JSObject::kGetterIndex)) {
+ if (callback_obj->IsAccessorPair()) {
+ AccessorPair* accessors = AccessorPair::cast(callback_obj);
+ if (Object* getter = accessors->getter()) {
SetPropertyReference(js_obj, entry, descs->GetKey(i),
getter, "get-%s");
}
- if (Object* setter = accessors->get(JSObject::kSetterIndex)) {
+ if (Object* setter = accessors->setter()) {
SetPropertyReference(js_obj, entry, descs->GetKey(i),
setter, "set-%s");
}
@@ -2285,7 +2289,7 @@ void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj,
}
}
} else if (js_obj->HasDictionaryElements()) {
- NumberDictionary* dictionary = js_obj->element_dictionary();
+ SeededNumberDictionary* dictionary = js_obj->element_dictionary();
int length = dictionary->Capacity();
for (int i = 0; i < length; ++i) {
Object* k = dictionary->KeyAt(i);
diff --git a/deps/v8/src/profile-generator.h b/deps/v8/src/profile-generator.h
index b47ce8255a..aefe1a0f60 100644
--- a/deps/v8/src/profile-generator.h
+++ b/deps/v8/src/profile-generator.h
@@ -750,7 +750,8 @@ class HeapObjectsMap {
static uint32_t AddressHash(Address addr) {
return ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(addr)));
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(addr)),
+ v8::internal::kZeroHashSeed);
}
bool initial_fill_mode_;
@@ -833,7 +834,7 @@ class HeapEntriesMap {
int total_children_count() { return total_children_count_; }
int total_retainers_count() { return total_retainers_count_; }
- static HeapEntry *const kHeapEntryPlaceholder;
+ static HeapEntry* const kHeapEntryPlaceholder;
private:
struct EntryInfo {
@@ -851,7 +852,8 @@ class HeapEntriesMap {
static uint32_t Hash(HeapThing thing) {
return ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)));
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)),
+ v8::internal::kZeroHashSeed);
}
static bool HeapThingsMatch(HeapThing key1, HeapThing key2) {
return key1 == key2;
@@ -1047,7 +1049,8 @@ class NativeObjectsExplorer : public HeapEntriesAllocator {
void VisitSubtreeWrapper(Object** p, uint16_t class_id);
static uint32_t InfoHash(v8::RetainedObjectInfo* info) {
- return ComputeIntegerHash(static_cast<uint32_t>(info->GetHash()));
+ return ComputeIntegerHash(static_cast<uint32_t>(info->GetHash()),
+ v8::internal::kZeroHashSeed);
}
static bool RetainedInfosMatch(void* key1, void* key2) {
return key1 == key2 ||
@@ -1125,7 +1128,8 @@ class HeapSnapshotJSONSerializer {
INLINE(static uint32_t ObjectHash(const void* key)) {
return ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)));
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)),
+ v8::internal::kZeroHashSeed);
}
void EnumerateNodes();
diff --git a/deps/v8/src/runtime-profiler.cc b/deps/v8/src/runtime-profiler.cc
index eaa6e15603..f89d98529b 100644
--- a/deps/v8/src/runtime-profiler.cc
+++ b/deps/v8/src/runtime-profiler.cc
@@ -65,7 +65,7 @@ Atomic32 RuntimeProfiler::state_ = 0;
Semaphore* RuntimeProfiler::semaphore_ = OS::CreateSemaphore(0);
#ifdef DEBUG
-bool RuntimeProfiler::has_been_globally_setup_ = false;
+bool RuntimeProfiler::has_been_globally_set_up_ = false;
#endif
bool RuntimeProfiler::enabled_ = false;
@@ -82,10 +82,10 @@ RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
void RuntimeProfiler::GlobalSetup() {
- ASSERT(!has_been_globally_setup_);
+ ASSERT(!has_been_globally_set_up_);
enabled_ = V8::UseCrankshaft() && FLAG_opt;
#ifdef DEBUG
- has_been_globally_setup_ = true;
+ has_been_globally_set_up_ = true;
#endif
}
@@ -245,8 +245,8 @@ void RuntimeProfiler::NotifyTick() {
}
-void RuntimeProfiler::Setup() {
- ASSERT(has_been_globally_setup_);
+void RuntimeProfiler::SetUp() {
+ ASSERT(has_been_globally_set_up_);
ClearSampleBuffer();
// If the ticker hasn't already started, make sure to do so to get
// the ticks for the runtime profiler.
diff --git a/deps/v8/src/runtime-profiler.h b/deps/v8/src/runtime-profiler.h
index 15c209713e..d35b5df847 100644
--- a/deps/v8/src/runtime-profiler.h
+++ b/deps/v8/src/runtime-profiler.h
@@ -46,7 +46,7 @@ class RuntimeProfiler {
static void GlobalSetup();
static inline bool IsEnabled() {
- ASSERT(has_been_globally_setup_);
+ ASSERT(has_been_globally_set_up_);
return enabled_;
}
@@ -54,7 +54,7 @@ class RuntimeProfiler {
void NotifyTick();
- void Setup();
+ void SetUp();
void Reset();
void TearDown();
@@ -126,7 +126,7 @@ class RuntimeProfiler {
static Semaphore* semaphore_;
#ifdef DEBUG
- static bool has_been_globally_setup_;
+ static bool has_been_globally_set_up_;
#endif
static bool enabled_;
};
diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc
index 811d72d91d..fb3621341a 100644
--- a/deps/v8/src/runtime.cc
+++ b/deps/v8/src/runtime.cc
@@ -228,7 +228,7 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
break;
}
case DICTIONARY_ELEMENTS: {
- NumberDictionary* element_dictionary = copy->element_dictionary();
+ SeededNumberDictionary* element_dictionary = copy->element_dictionary();
int capacity = element_dictionary->Capacity();
for (int i = 0; i < capacity; i++) {
Object* k = element_dictionary->KeyAt(i);
@@ -355,7 +355,7 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
Handle<JSObject> boilerplate = isolate->factory()->NewJSObjectFromMap(map);
// Normalize the elements of the boilerplate to save space if needed.
- if (!should_have_fast_elements) NormalizeElements(boilerplate);
+ if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
// Add the constant properties to the boilerplate.
int length = constant_properties->length();
@@ -365,7 +365,8 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
// Normalize the properties of object to avoid n^2 behavior
// when extending the object multiple properties. Indicate the number of
// properties to be added.
- NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
+ JSObject::NormalizeProperties(
+ boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
}
for (int index = 0; index < length; index +=2) {
@@ -383,22 +384,18 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
if (key->IsSymbol()) {
if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
// Array index as string (uint32).
- result = SetOwnElement(boilerplate,
- element_index,
- value,
- kNonStrictMode);
+ result = JSObject::SetOwnElement(
+ boilerplate, element_index, value, kNonStrictMode);
} else {
Handle<String> name(String::cast(*key));
ASSERT(!name->AsArrayIndex(&element_index));
- result = SetLocalPropertyIgnoreAttributes(boilerplate, name,
- value, NONE);
+ result = JSObject::SetLocalPropertyIgnoreAttributes(
+ boilerplate, name, value, NONE);
}
} else if (key->ToArrayIndex(&element_index)) {
// Array index (uint32).
- result = SetOwnElement(boilerplate,
- element_index,
- value,
- kNonStrictMode);
+ result = JSObject::SetOwnElement(
+ boilerplate, element_index, value, kNonStrictMode);
} else {
// Non-uint32 number.
ASSERT(key->IsNumber());
@@ -408,8 +405,8 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
const char* str = DoubleToCString(num, buffer);
Handle<String> name =
isolate->factory()->NewStringFromAscii(CStrVector(str));
- result = SetLocalPropertyIgnoreAttributes(boilerplate, name,
- value, NONE);
+ result = JSObject::SetLocalPropertyIgnoreAttributes(
+ boilerplate, name, value, NONE);
}
// If setting the property on the boilerplate throws an
// exception, the exception is converted to an empty handle in
@@ -423,8 +420,8 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
// computed properties have been assigned so that we can generate
// constant function properties.
if (should_transform && !has_function_literal) {
- TransformToFastProperties(boilerplate,
- boilerplate->map()->unused_property_fields());
+ JSObject::TransformToFastProperties(
+ boilerplate, boilerplate->map()->unused_property_fields());
}
return boilerplate;
@@ -434,7 +431,6 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
static const int kSmiOnlyLiteralMinimumLength = 1024;
-// static
Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
Isolate* isolate,
Handle<FixedArray> literals,
@@ -1048,26 +1044,26 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
holder = Handle<JSObject>(JSObject::cast(proto));
}
FixedArray* elements = FixedArray::cast(holder->elements());
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
if (elements->map() == heap->non_strict_arguments_elements_map()) {
- dictionary = NumberDictionary::cast(elements->get(1));
+ dictionary = SeededNumberDictionary::cast(elements->get(1));
} else {
- dictionary = NumberDictionary::cast(elements);
+ dictionary = SeededNumberDictionary::cast(elements);
}
int entry = dictionary->FindEntry(index);
- ASSERT(entry != NumberDictionary::kNotFound);
+ ASSERT(entry != SeededNumberDictionary::kNotFound);
PropertyDetails details = dictionary->DetailsAt(entry);
switch (details.type()) {
case CALLBACKS: {
// This is an accessor property with getter and/or setter.
- FixedArray* callbacks =
- FixedArray::cast(dictionary->ValueAt(entry));
+ AccessorPair* accessors =
+ AccessorPair::cast(dictionary->ValueAt(entry));
elms->set(IS_ACCESSOR_INDEX, heap->true_value());
if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) {
- elms->set(GETTER_INDEX, callbacks->get(0));
+ elms->set(GETTER_INDEX, accessors->getter());
}
if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) {
- elms->set(SETTER_INDEX, callbacks->get(1));
+ elms->set(SETTER_INDEX, accessors->setter());
}
break;
}
@@ -1106,18 +1102,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete()));
bool is_js_accessor = (result.type() == CALLBACKS) &&
- (result.GetCallbackObject()->IsFixedArray());
+ (result.GetCallbackObject()->IsAccessorPair());
if (is_js_accessor) {
// __defineGetter__/__defineSetter__ callback.
elms->set(IS_ACCESSOR_INDEX, heap->true_value());
- FixedArray* structure = FixedArray::cast(result.GetCallbackObject());
+ AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject());
if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) {
- elms->set(GETTER_INDEX, structure->get(0));
+ elms->set(GETTER_INDEX, accessors->getter());
}
if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) {
- elms->set(SETTER_INDEX, structure->get(1));
+ elms->set(SETTER_INDEX, accessors->setter());
}
} else {
elms->set(IS_ACCESSOR_INDEX, heap->false_value());
@@ -1335,21 +1331,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
}
PropertyAttributes attributes = static_cast<PropertyAttributes>(attr);
- RETURN_IF_EMPTY_HANDLE(isolate,
- SetLocalPropertyIgnoreAttributes(global,
- name,
- value,
- attributes));
+ RETURN_IF_EMPTY_HANDLE(
+ isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
+ attributes));
} else {
LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags);
StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
? kNonStrictMode : kStrictMode;
- RETURN_IF_EMPTY_HANDLE(isolate,
- SetProperty(global,
- name,
- value,
- static_cast<PropertyAttributes>(attr),
- strict_mode_flag));
+ RETURN_IF_EMPTY_HANDLE(
+ isolate,
+ JSReceiver::SetProperty(global, name, value,
+ static_cast<PropertyAttributes>(attr),
+ strict_mode_flag));
}
}
@@ -1403,7 +1397,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
Handle<JSObject> object = Handle<JSObject>::cast(holder);
RETURN_IF_EMPTY_HANDLE(
isolate,
- SetProperty(object, name, initial_value, mode, kNonStrictMode));
+ JSReceiver::SetProperty(object, name, initial_value, mode,
+ kNonStrictMode));
}
}
@@ -1443,9 +1438,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
return ThrowRedeclarationError(isolate, "const", name);
}
}
- RETURN_IF_EMPTY_HANDLE(isolate,
- SetProperty(object, name, value, mode,
- kNonStrictMode));
+ RETURN_IF_EMPTY_HANDLE(
+ isolate,
+ JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode));
}
return isolate->heap()->undefined_value();
@@ -1554,12 +1549,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
// property through an interceptor and only do it if it's
// uninitialized, e.g. the hole. Nirk...
// Passing non-strict mode because the property is writable.
- RETURN_IF_EMPTY_HANDLE(isolate,
- SetProperty(global,
- name,
- value,
- attributes,
- kNonStrictMode));
+ RETURN_IF_EMPTY_HANDLE(
+ isolate,
+ JSReceiver::SetProperty(global, name, value, attributes,
+ kNonStrictMode));
return *value;
}
@@ -1629,7 +1622,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
// Strict mode not needed (const disallowed in strict mode).
RETURN_IF_EMPTY_HANDLE(
isolate,
- SetProperty(global, name, value, NONE, kNonStrictMode));
+ JSReceiver::SetProperty(global, name, value, NONE, kNonStrictMode));
return *value;
}
@@ -1681,7 +1674,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
// Strict mode not needed (const disallowed in strict mode).
RETURN_IF_EMPTY_HANDLE(
isolate,
- SetProperty(object, name, value, attributes, kNonStrictMode));
+ JSReceiver::SetProperty(object, name, value, attributes,
+ kNonStrictMode));
}
}
@@ -1696,7 +1690,7 @@ RUNTIME_FUNCTION(MaybeObject*,
CONVERT_ARG_CHECKED(JSObject, object, 0);
CONVERT_SMI_ARG_CHECKED(properties, 1);
if (object->HasFastProperties()) {
- NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
+ JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
}
return *object;
}
@@ -1852,7 +1846,7 @@ static Handle<JSFunction> InstallBuiltin(Isolate* isolate,
code,
false);
optimized->shared()->DontAdaptArguments();
- SetProperty(holder, key, optimized, NONE, kStrictMode);
+ JSReceiver::SetProperty(holder, key, optimized, NONE, kStrictMode);
return optimized;
}
@@ -4066,8 +4060,7 @@ MaybeObject* Runtime::GetElementOrCharAt(Isolate* isolate,
}
if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
- Handle<Object> prototype = GetPrototype(object);
- return prototype->GetElement(index);
+ return object->GetPrototype()->GetElement(index);
}
return object->GetElement(index);
@@ -4134,8 +4127,8 @@ MaybeObject* TransitionElements(Handle<Object> object,
ElementsKind from_kind =
Handle<JSObject>::cast(object)->map()->elements_kind();
if (Map::IsValidElementsTransition(from_kind, to_kind)) {
- Handle<Object> result =
- TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
+ Handle<Object> result = JSObject::TransitionElementsKind(
+ Handle<JSObject>::cast(object), to_kind);
if (result.is_null()) return isolate->ThrowIllegalOperation();
return *result;
}
@@ -4307,12 +4300,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
return isolate->Throw(*error);
}
- Handle<NumberDictionary> dictionary = NormalizeElements(js_object);
+ Handle<SeededNumberDictionary> dictionary =
+ JSObject::NormalizeElements(js_object);
// Make sure that we never go back to fast case.
dictionary->set_requires_slow_elements();
PropertyDetails details = PropertyDetails(attr, NORMAL);
- Handle<NumberDictionary> extended_dictionary =
- NumberDictionarySet(dictionary, index, obj_value, details);
+ Handle<SeededNumberDictionary> extended_dictionary =
+ SeededNumberDictionary::Set(dictionary, index, obj_value, details);
if (*extended_dictionary != *dictionary) {
if (js_object->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) {
FixedArray::cast(js_object->elements())->set(1, *extended_dictionary);
@@ -4362,7 +4356,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
// we don't have to check for null.
js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
}
- NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
+ JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
// Use IgnoreAttributes version since a readonly property may be
// overridden and SetProperty does not allow this.
return js_object->SetLocalPropertyIgnoreAttributes(*name,
@@ -4387,12 +4381,13 @@ static MaybeObject* NormalizeObjectSetElement(Isolate* isolate,
Handle<Object> value,
PropertyAttributes attr) {
// Normalize the elements to enable attributes on the property.
- Handle<NumberDictionary> dictionary = NormalizeElements(js_object);
+ Handle<SeededNumberDictionary> dictionary =
+ JSObject::NormalizeElements(js_object);
// Make sure that we never go back to fast case.
dictionary->set_requires_slow_elements();
PropertyDetails details = PropertyDetails(attr, NORMAL);
- Handle<NumberDictionary> extended_dictionary =
- NumberDictionarySet(dictionary, index, value, details);
+ Handle<SeededNumberDictionary> extended_dictionary =
+ SeededNumberDictionary::Set(dictionary, index, value, details);
if (*extended_dictionary != *dictionary) {
js_object->set_elements(*extended_dictionary);
}
@@ -4447,7 +4442,8 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
return NormalizeObjectSetElement(isolate, js_object, index, value, attr);
}
- Handle<Object> result = SetElement(js_object, index, value, strict_mode);
+ Handle<Object> result =
+ JSObject::SetElement(js_object, index, value, strict_mode);
if (result.is_null()) return Failure::Exception();
return *value;
}
@@ -4462,11 +4458,13 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
value,
attr);
}
- result = SetElement(js_object, index, value, strict_mode);
+ result =
+ JSObject::SetElement(js_object, index, value, strict_mode);
} else {
Handle<String> key_string = Handle<String>::cast(key);
key_string->TryFlatten();
- result = SetProperty(js_object, key_string, value, attr, strict_mode);
+ result = JSReceiver::SetProperty(
+ js_object, key_string, value, attr, strict_mode);
}
if (result.is_null()) return Failure::Exception();
return *value;
@@ -4655,8 +4653,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
if (value->IsNumber()) {
ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS);
- TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS);
- TransitionElementsKind(boilerplate_object, FAST_DOUBLE_ELEMENTS);
+ JSObject::TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS);
+ JSObject::TransitionElementsKind(boilerplate_object, FAST_DOUBLE_ELEMENTS);
ASSERT(object->GetElementsKind() == FAST_DOUBLE_ELEMENTS);
FixedDoubleArray* double_array =
FixedDoubleArray::cast(object->elements());
@@ -4665,8 +4663,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
} else {
ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS ||
elements_kind == FAST_DOUBLE_ELEMENTS);
- TransitionElementsKind(object, FAST_ELEMENTS);
- TransitionElementsKind(boilerplate_object, FAST_ELEMENTS);
+ JSObject::TransitionElementsKind(object, FAST_ELEMENTS);
+ JSObject::TransitionElementsKind(boilerplate_object, FAST_ELEMENTS);
FixedArray* object_array =
FixedArray::cast(object->elements());
object_array->set(store_index, *value);
@@ -4818,15 +4816,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
object = JSObject::cast(proto);
}
FixedArray* elements = FixedArray::cast(object->elements());
- NumberDictionary* dictionary = NULL;
+ SeededNumberDictionary* dictionary = NULL;
if (elements->map() ==
isolate->heap()->non_strict_arguments_elements_map()) {
- dictionary = NumberDictionary::cast(elements->get(1));
+ dictionary = SeededNumberDictionary::cast(elements->get(1));
} else {
- dictionary = NumberDictionary::cast(elements);
+ dictionary = SeededNumberDictionary::cast(elements);
}
int entry = dictionary->FindEntry(index);
- ASSERT(entry != NumberDictionary::kNotFound);
+ ASSERT(entry != SeededNumberDictionary::kNotFound);
PropertyDetails details = dictionary->DetailsAt(entry);
return isolate->heap()->ToBoolean(!details.IsDontEnum());
}
@@ -5144,31 +5142,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) {
- HandleScope scope(isolate);
-
ASSERT(args.length() == 1);
- Handle<Object> object = args.at<Object>(0);
- if (object->IsJSObject()) {
- Handle<JSObject> js_object = Handle<JSObject>::cast(object);
- if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) {
- MaybeObject* ok = js_object->TransformToFastProperties(0);
- if (ok->IsRetryAfterGC()) return ok;
- }
- }
- return *object;
+ Object* object = args[0];
+ return (object->IsJSObject() && !object->IsGlobalObject())
+ ? JSObject::cast(object)->TransformToFastProperties(0)
+ : object;
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_ToSlowProperties) {
- HandleScope scope(isolate);
-
ASSERT(args.length() == 1);
- Handle<Object> object = args.at<Object>(0);
- if (object->IsJSObject() && !object->IsJSGlobalProxy()) {
- Handle<JSObject> js_object = Handle<JSObject>::cast(object);
- NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
- }
- return *object;
+ Object* obj = args[0];
+ return (obj->IsJSObject() && !obj->IsJSGlobalProxy())
+ ? JSObject::cast(obj)->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0)
+ : obj;
}
@@ -9133,7 +9120,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
(object->GetLocalPropertyAttribute(*name) == ABSENT)) {
RETURN_IF_EMPTY_HANDLE(
isolate,
- SetProperty(object, name, value, NONE, strict_mode));
+ JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
} else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) {
// Setting read only property in strict mode.
Handle<Object> error =
@@ -9386,20 +9373,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
bool CodeGenerationFromStringsAllowed(Isolate* isolate,
Handle<Context> context) {
- if (context->allow_code_gen_from_strings()->IsFalse()) {
- // Check with callback if set.
- AllowCodeGenerationFromStringsCallback callback =
- isolate->allow_code_gen_callback();
- if (callback == NULL) {
- // No callback set and code generation disallowed.
- return false;
- } else {
- // Callback set. Let it decide if code generation is allowed.
- VMState state(isolate, EXTERNAL);
- return callback(v8::Utils::ToLocal(context));
- }
+ ASSERT(context->allow_code_gen_from_strings()->IsFalse());
+ // Check with callback if set.
+ AllowCodeGenerationFromStringsCallback callback =
+ isolate->allow_code_gen_callback();
+ if (callback == NULL) {
+ // No callback set and code generation disallowed.
+ return false;
+ } else {
+ // Callback set. Let it decide if code generation is allowed.
+ VMState state(isolate, EXTERNAL);
+ return callback(v8::Utils::ToLocal(context));
}
- return true;
}
@@ -9413,7 +9398,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
// Check if global context allows code generation from
// strings. Throw an exception if it doesn't.
- if (!CodeGenerationFromStringsAllowed(isolate, context)) {
+ if (context->allow_code_gen_from_strings()->IsFalse() &&
+ !CodeGenerationFromStringsAllowed(isolate, context)) {
return isolate->Throw(*isolate->factory()->NewError(
"code_gen_from_strings", HandleVector<Object>(NULL, 0)));
}
@@ -9440,7 +9426,8 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
// Check if global context allows code generation from
// strings. Throw an exception if it doesn't.
- if (!CodeGenerationFromStringsAllowed(isolate, global_context)) {
+ if (global_context->allow_code_gen_from_strings()->IsFalse() &&
+ !CodeGenerationFromStringsAllowed(isolate, global_context)) {
isolate->Throw(*isolate->factory()->NewError(
"code_gen_from_strings", HandleVector<Object>(NULL, 0)));
return MakePair(Failure::Exception(), NULL);
@@ -9596,8 +9583,9 @@ class ArrayConcatVisitor {
// Fall-through to dictionary mode.
}
ASSERT(!fast_elements_);
- Handle<NumberDictionary> dict(NumberDictionary::cast(*storage_));
- Handle<NumberDictionary> result =
+ Handle<SeededNumberDictionary> dict(
+ SeededNumberDictionary::cast(*storage_));
+ Handle<SeededNumberDictionary> result =
isolate_->factory()->DictionaryAtNumberPut(dict, index, elm);
if (!result.is_identical_to(dict)) {
// Dictionary needed to grow.
@@ -9637,14 +9625,15 @@ class ArrayConcatVisitor {
void SetDictionaryMode(uint32_t index) {
ASSERT(fast_elements_);
Handle<FixedArray> current_storage(*storage_);
- Handle<NumberDictionary> slow_storage(
- isolate_->factory()->NewNumberDictionary(current_storage->length()));
+ Handle<SeededNumberDictionary> slow_storage(
+ isolate_->factory()->NewSeededNumberDictionary(
+ current_storage->length()));
uint32_t current_length = static_cast<uint32_t>(current_storage->length());
for (uint32_t i = 0; i < current_length; i++) {
HandleScope loop_scope;
Handle<Object> element(current_storage->get(i));
if (!element->IsTheHole()) {
- Handle<NumberDictionary> new_storage =
+ Handle<SeededNumberDictionary> new_storage =
isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element);
if (!new_storage.is_identical_to(slow_storage)) {
slow_storage = loop_scope.CloseAndEscape(new_storage);
@@ -9696,8 +9685,8 @@ static uint32_t EstimateElementCount(Handle<JSArray> array) {
UNREACHABLE();
break;
case DICTIONARY_ELEMENTS: {
- Handle<NumberDictionary> dictionary(
- NumberDictionary::cast(array->elements()));
+ Handle<SeededNumberDictionary> dictionary(
+ SeededNumberDictionary::cast(array->elements()));
int capacity = dictionary->Capacity();
for (int i = 0; i < capacity; i++) {
Handle<Object> key(dictionary->KeyAt(i));
@@ -9800,7 +9789,8 @@ static void CollectElementIndices(Handle<JSObject> object,
break;
}
case DICTIONARY_ELEMENTS: {
- Handle<NumberDictionary> dict(NumberDictionary::cast(object->elements()));
+ Handle<SeededNumberDictionary> dict(
+ SeededNumberDictionary::cast(object->elements()));
uint32_t capacity = dict->Capacity();
for (uint32_t j = 0; j < capacity; j++) {
HandleScope loop_scope;
@@ -9935,7 +9925,7 @@ static bool IterateElements(Isolate* isolate,
break;
}
case DICTIONARY_ELEMENTS: {
- Handle<NumberDictionary> dict(receiver->element_dictionary());
+ Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
List<uint32_t> indices(dict->Capacity() / 2);
// Collect all indices in the object and the prototypes less
// than length. This might introduce duplicates in the indices list.
@@ -10049,7 +10039,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
// FAST_ELEMENTS.
if (array->HasFastDoubleElements()) {
array = Handle<JSArray>::cast(
- TransitionElementsKind(array, FAST_ELEMENTS));
+ JSObject::TransitionElementsKind(array, FAST_ELEMENTS));
}
length_estimate =
static_cast<uint32_t>(array->length()->Number());
@@ -10091,7 +10081,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
uint32_t at_least_space_for = estimate_nof_elements +
(estimate_nof_elements >> 2);
storage = Handle<FixedArray>::cast(
- isolate->factory()->NewNumberDictionary(at_least_space_for));
+ isolate->factory()->NewSeededNumberDictionary(at_least_space_for));
}
ArrayConcatVisitor visitor(isolate, storage, fast_case);
@@ -10179,7 +10169,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) {
CONVERT_CHECKED(JSObject, object, args[0]);
HeapObject* elements = object->elements();
if (elements->IsDictionary()) {
- return Smi::FromInt(NumberDictionary::cast(elements)->NumberOfElements());
+ int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
+ return Smi::FromInt(result);
} else if (object->IsJSArray()) {
return JSArray::cast(object)->length();
} else {
@@ -10209,10 +10200,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SwapElements) {
Handle<Object> tmp2 = Object::GetElement(jsobject, index2);
RETURN_IF_EMPTY_HANDLE(isolate, tmp2);
- RETURN_IF_EMPTY_HANDLE(isolate,
- SetElement(jsobject, index1, tmp2, kStrictMode));
- RETURN_IF_EMPTY_HANDLE(isolate,
- SetElement(jsobject, index2, tmp1, kStrictMode));
+ RETURN_IF_EMPTY_HANDLE(
+ isolate, JSObject::SetElement(jsobject, index1, tmp2, kStrictMode));
+ RETURN_IF_EMPTY_HANDLE(
+ isolate, JSObject::SetElement(jsobject, index2, tmp1, kStrictMode));
return isolate->heap()->undefined_value();
}
@@ -10488,15 +10479,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
// If the callback object is a fixed array then it contains JavaScript
// getter and/or setter.
bool hasJavaScriptAccessors = result_type == CALLBACKS &&
- result_callback_obj->IsFixedArray();
+ result_callback_obj->IsAccessorPair();
Handle<FixedArray> details =
isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
details->set(0, *value);
details->set(1, property_details);
if (hasJavaScriptAccessors) {
details->set(2, isolate->heap()->ToBoolean(caught_exception));
- details->set(3, FixedArray::cast(*result_callback_obj)->get(0));
- details->set(4, FixedArray::cast(*result_callback_obj)->get(1));
+ details->set(3, AccessorPair::cast(*result_callback_obj)->getter());
+ details->set(4, AccessorPair::cast(*result_callback_obj)->setter());
}
return *isolate->factory()->NewJSArrayWithElements(details);
diff --git a/deps/v8/src/scopes.cc b/deps/v8/src/scopes.cc
index 4a6d0a7fae..d0ee8ec7f2 100644
--- a/deps/v8/src/scopes.cc
+++ b/deps/v8/src/scopes.cc
@@ -808,7 +808,7 @@ void Scope::Print(int n) {
PrintF(")");
}
- PrintF(" {\n");
+ PrintF(" { // (%d, %d)\n", start_position(), end_position());
// Function name, if any (named function literals, only).
if (function_ != NULL) {
diff --git a/deps/v8/src/spaces.cc b/deps/v8/src/spaces.cc
index ebd3e65192..c8e94ddbe5 100644
--- a/deps/v8/src/spaces.cc
+++ b/deps/v8/src/spaces.cc
@@ -132,7 +132,7 @@ CodeRange::CodeRange(Isolate* isolate)
}
-bool CodeRange::Setup(const size_t requested) {
+bool CodeRange::SetUp(const size_t requested) {
ASSERT(code_range_ == NULL);
code_range_ = new VirtualMemory(requested);
@@ -268,7 +268,7 @@ MemoryAllocator::MemoryAllocator(Isolate* isolate)
}
-bool MemoryAllocator::Setup(intptr_t capacity, intptr_t capacity_executable) {
+bool MemoryAllocator::SetUp(intptr_t capacity, intptr_t capacity_executable) {
capacity_ = RoundUp(capacity, Page::kPageSize);
capacity_executable_ = RoundUp(capacity_executable, Page::kPageSize);
ASSERT_GE(capacity_, capacity_executable_);
@@ -658,7 +658,8 @@ PagedSpace::PagedSpace(Heap* heap,
: Space(heap, id, executable),
free_list_(this),
was_swept_conservatively_(false),
- first_unswept_page_(Page::FromAddress(NULL)) {
+ first_unswept_page_(Page::FromAddress(NULL)),
+ unswept_free_bytes_(0) {
max_capacity_ = (RoundDown(max_capacity, Page::kPageSize) / Page::kPageSize)
* Page::kObjectAreaSize;
accounting_stats_.Clear();
@@ -670,12 +671,12 @@ PagedSpace::PagedSpace(Heap* heap,
}
-bool PagedSpace::Setup() {
+bool PagedSpace::SetUp() {
return true;
}
-bool PagedSpace::HasBeenSetup() {
+bool PagedSpace::HasBeenSetUp() {
return true;
}
@@ -873,9 +874,9 @@ void PagedSpace::Verify(ObjectVisitor* visitor) {
// NewSpace implementation
-bool NewSpace::Setup(int reserved_semispace_capacity,
+bool NewSpace::SetUp(int reserved_semispace_capacity,
int maximum_semispace_capacity) {
- // Setup new space based on the preallocated memory block defined by
+ // Set up new space based on the preallocated memory block defined by
// start and size. The provided space is divided into two semi-spaces.
// To support fast containment testing in the new space, the size of
// this chunk must be a power of two and it must be aligned to its size.
@@ -894,7 +895,7 @@ bool NewSpace::Setup(int reserved_semispace_capacity,
ASSERT(initial_semispace_capacity <= maximum_semispace_capacity);
ASSERT(IsPowerOf2(maximum_semispace_capacity));
- // Allocate and setup the histogram arrays if necessary.
+ // Allocate and set up the histogram arrays if necessary.
allocated_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1);
promoted_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1);
@@ -908,12 +909,12 @@ bool NewSpace::Setup(int reserved_semispace_capacity,
2 * heap()->ReservedSemiSpaceSize());
ASSERT(IsAddressAligned(chunk_base_, 2 * reserved_semispace_capacity, 0));
- if (!to_space_.Setup(chunk_base_,
+ if (!to_space_.SetUp(chunk_base_,
initial_semispace_capacity,
maximum_semispace_capacity)) {
return false;
}
- if (!from_space_.Setup(chunk_base_ + reserved_semispace_capacity,
+ if (!from_space_.SetUp(chunk_base_ + reserved_semispace_capacity,
initial_semispace_capacity,
maximum_semispace_capacity)) {
return false;
@@ -1148,7 +1149,7 @@ void NewSpace::Verify() {
// -----------------------------------------------------------------------------
// SemiSpace implementation
-bool SemiSpace::Setup(Address start,
+bool SemiSpace::SetUp(Address start,
int initial_capacity,
int maximum_capacity) {
// Creates a space in the young generation. The constructor does not
@@ -2062,6 +2063,7 @@ void PagedSpace::PrepareForMarkCompact() {
} while (p != anchor());
}
first_unswept_page_ = Page::FromAddress(NULL);
+ unswept_free_bytes_ = 0;
// Clear the free list before a full GC---it will be rebuilt afterward.
free_list_.Reset();
@@ -2110,6 +2112,7 @@ bool PagedSpace::AdvanceSweeper(intptr_t bytes_to_sweep) {
PrintF("Sweeping 0x%" V8PRIxPTR " lazily advanced.\n",
reinterpret_cast<intptr_t>(p));
}
+ unswept_free_bytes_ -= (Page::kObjectAreaSize - p->LiveBytes());
freed_bytes += MarkCompactCollector::SweepConservatively(this, p);
}
p = next_page;
@@ -2408,7 +2411,7 @@ LargeObjectSpace::LargeObjectSpace(Heap* heap,
objects_size_(0) {}
-bool LargeObjectSpace::Setup() {
+bool LargeObjectSpace::SetUp() {
first_page_ = NULL;
size_ = 0;
page_count_ = 0;
@@ -2428,7 +2431,7 @@ void LargeObjectSpace::TearDown() {
space, kAllocationActionFree, page->size());
heap()->isolate()->memory_allocator()->Free(page);
}
- Setup();
+ SetUp();
}
diff --git a/deps/v8/src/spaces.h b/deps/v8/src/spaces.h
index 41bfec90f1..41c3ef929f 100644
--- a/deps/v8/src/spaces.h
+++ b/deps/v8/src/spaces.h
@@ -815,7 +815,7 @@ class CodeRange {
// Reserves a range of virtual memory, but does not commit any of it.
// Can only be called once, at heap initialization time.
// Returns false on failure.
- bool Setup(const size_t requested_size);
+ bool SetUp(const size_t requested_size);
// Frees the range of virtual memory, and frees the data structures used to
// manage it.
@@ -943,7 +943,7 @@ class MemoryAllocator {
// Initializes its internal bookkeeping structures.
// Max capacity of the total space and executable memory limit.
- bool Setup(intptr_t max_capacity, intptr_t capacity_executable);
+ bool SetUp(intptr_t max_capacity, intptr_t capacity_executable);
void TearDown();
@@ -1419,11 +1419,11 @@ class PagedSpace : public Space {
// the memory allocator's initial chunk) if possible. If the block of
// addresses is not big enough to contain a single page-aligned page, a
// fresh chunk will be allocated.
- bool Setup();
+ bool SetUp();
// Returns true if the space has been successfully set up and not
// subsequently torn down.
- bool HasBeenSetup();
+ bool HasBeenSetUp();
// Cleans up the space, frees all pages in this space except those belonging
// to the initial chunk, uncommits addresses in the initial chunk.
@@ -1469,9 +1469,12 @@ class PagedSpace : public Space {
// linear allocation area (between top and limit) are also counted here.
virtual intptr_t Size() { return accounting_stats_.Size(); }
- // As size, but the bytes in the current linear allocation area are not
- // included.
- virtual intptr_t SizeOfObjects() { return Size() - (limit() - top()); }
+ // As size, but the bytes in lazily swept pages are estimated and the bytes
+ // in the current linear allocation area are not included.
+ virtual intptr_t SizeOfObjects() {
+ ASSERT(!IsSweepingComplete() || (unswept_free_bytes_ == 0));
+ return Size() - unswept_free_bytes_ - (limit() - top());
+ }
// Wasted bytes in this space. These are just the bytes that were thrown away
// due to being too small to use for allocation. They do not include the
@@ -1479,9 +1482,7 @@ class PagedSpace : public Space {
virtual intptr_t Waste() { return accounting_stats_.Waste(); }
// Returns the allocation pointer in this space.
- Address top() {
- return allocation_info_.top;
- }
+ Address top() { return allocation_info_.top; }
Address limit() { return allocation_info_.limit; }
// Allocate the requested number of bytes in the space if possible, return a
@@ -1557,10 +1558,15 @@ class PagedSpace : public Space {
}
void SetPagesToSweep(Page* first) {
+ ASSERT(unswept_free_bytes_ == 0);
if (first == &anchor_) first = NULL;
first_unswept_page_ = first;
}
+ void MarkPageForLazySweeping(Page* p) {
+ unswept_free_bytes_ += (Page::kObjectAreaSize - p->LiveBytes());
+ }
+
bool AdvanceSweeper(intptr_t bytes_to_sweep);
bool IsSweepingComplete() {
@@ -1647,8 +1653,15 @@ class PagedSpace : public Space {
bool was_swept_conservatively_;
+ // The first page to be swept when the lazy sweeper advances. Is set
+ // to NULL when all pages have been swept.
Page* first_unswept_page_;
+ // The number of free bytes which could be reclaimed by advancing the
+ // lazy sweeper. This is only an estimation because lazy sweeping is
+ // done conservatively.
+ intptr_t unswept_free_bytes_;
+
// Expands the space by allocating a fixed number of pages. Returns false if
// it cannot allocate requested number of pages from OS, or if the hard heap
// size limit has been hit.
@@ -1808,14 +1821,14 @@ class SemiSpace : public Space {
current_page_(NULL) { }
// Sets up the semispace using the given chunk.
- bool Setup(Address start, int initial_capacity, int maximum_capacity);
+ bool SetUp(Address start, int initial_capacity, int maximum_capacity);
// Tear down the space. Heap memory was not allocated by the space, so it
// is not deallocated here.
void TearDown();
// True if the space has been set up but not torn down.
- bool HasBeenSetup() { return start_ != NULL; }
+ bool HasBeenSetUp() { return start_ != NULL; }
// Grow the semispace to the new capacity. The new capacity
// requested must be larger than the current capacity and less than
@@ -2054,15 +2067,15 @@ class NewSpace : public Space {
inline_allocation_limit_step_(0) {}
// Sets up the new space using the given chunk.
- bool Setup(int reserved_semispace_size_, int max_semispace_size);
+ bool SetUp(int reserved_semispace_size_, int max_semispace_size);
// Tears down the space. Heap memory was not allocated by the space, so it
// is not deallocated here.
void TearDown();
// True if the space has been set up but not torn down.
- bool HasBeenSetup() {
- return to_space_.HasBeenSetup() && from_space_.HasBeenSetup();
+ bool HasBeenSetUp() {
+ return to_space_.HasBeenSetUp() && from_space_.HasBeenSetUp();
}
// Flip the pair of spaces.
@@ -2461,7 +2474,7 @@ class LargeObjectSpace : public Space {
virtual ~LargeObjectSpace() {}
// Initializes internal data structures.
- bool Setup();
+ bool SetUp();
// Releases internal resources, frees objects in this space.
void TearDown();
diff --git a/deps/v8/src/store-buffer.cc b/deps/v8/src/store-buffer.cc
index 0f1fed0286..9022b3be83 100644
--- a/deps/v8/src/store-buffer.cc
+++ b/deps/v8/src/store-buffer.cc
@@ -55,7 +55,7 @@ StoreBuffer::StoreBuffer(Heap* heap)
}
-void StoreBuffer::Setup() {
+void StoreBuffer::SetUp() {
virtual_memory_ = new VirtualMemory(kStoreBufferSize * 3);
uintptr_t start_as_int =
reinterpret_cast<uintptr_t>(virtual_memory_->address());
diff --git a/deps/v8/src/store-buffer.h b/deps/v8/src/store-buffer.h
index 204fa3ff4e..951a9ca2bc 100644
--- a/deps/v8/src/store-buffer.h
+++ b/deps/v8/src/store-buffer.h
@@ -54,7 +54,7 @@ class StoreBuffer {
inline Address TopAddress();
- void Setup();
+ void SetUp();
void TearDown();
// This is used by the mutator to enter addresses into the store buffer.
diff --git a/deps/v8/src/stub-cache.cc b/deps/v8/src/stub-cache.cc
index 787e833f4f..ec8f6bdf25 100644
--- a/deps/v8/src/stub-cache.cc
+++ b/deps/v8/src/stub-cache.cc
@@ -678,11 +678,10 @@ Handle<Code> StubCache::ComputeCallGlobal(int argc,
static void FillCache(Isolate* isolate, Handle<Code> code) {
- Handle<NumberDictionary> dictionary =
- NumberDictionarySet(isolate->factory()->non_monomorphic_cache(),
- code->flags(),
- code,
- PropertyDetails(NONE, NORMAL));
+ Handle<UnseededNumberDictionary> dictionary =
+ UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
+ code->flags(),
+ code);
isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
}
@@ -697,7 +696,7 @@ Code* StubCache::FindCallInitialize(int argc,
Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
// Use raw_unchecked... so we don't get assert failures during GC.
- NumberDictionary* dictionary =
+ UnseededNumberDictionary* dictionary =
isolate()->heap()->raw_unchecked_non_monomorphic_cache();
int entry = dictionary->FindEntry(isolate(), flags);
ASSERT(entry != -1);
@@ -716,7 +715,8 @@ Handle<Code> StubCache::ComputeCallInitialize(int argc,
CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
Code::Flags flags =
Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
- Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
+ Handle<UnseededNumberDictionary> cache =
+ isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
@@ -744,7 +744,8 @@ Handle<Code> StubCache::ComputeCallPreMonomorphic(
Code::ExtraICState extra_state) {
Code::Flags flags =
Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, NORMAL, argc);
- Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
+ Handle<UnseededNumberDictionary> cache =
+ isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
@@ -760,7 +761,8 @@ Handle<Code> StubCache::ComputeCallNormal(int argc,
Code::ExtraICState extra_state) {
Code::Flags flags =
Code::ComputeFlags(kind, MONOMORPHIC, extra_state, NORMAL, argc);
- Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
+ Handle<UnseededNumberDictionary> cache =
+ isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
@@ -776,7 +778,8 @@ Handle<Code> StubCache::ComputeCallArguments(int argc, Code::Kind kind) {
Code::Flags flags =
Code::ComputeFlags(kind, MEGAMORPHIC, Code::kNoExtraICState,
NORMAL, argc);
- Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
+ Handle<UnseededNumberDictionary> cache =
+ isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
@@ -794,7 +797,8 @@ Handle<Code> StubCache::ComputeCallMegamorphic(
Code::Flags flags =
Code::ComputeFlags(kind, MEGAMORPHIC, extra_state,
NORMAL, argc);
- Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
+ Handle<UnseededNumberDictionary> cache =
+ isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
@@ -813,7 +817,8 @@ Handle<Code> StubCache::ComputeCallMiss(int argc,
Code::Flags flags =
Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state,
NORMAL, argc, OWN_MAP);
- Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
+ Handle<UnseededNumberDictionary> cache =
+ isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
@@ -832,7 +837,8 @@ Handle<Code> StubCache::ComputeCallDebugBreak(int argc,
Code::Flags flags =
Code::ComputeFlags(kind, DEBUG_BREAK, Code::kNoExtraICState,
NORMAL, argc);
- Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
+ Handle<UnseededNumberDictionary> cache =
+ isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
@@ -850,7 +856,8 @@ Handle<Code> StubCache::ComputeCallDebugPrepareStepIn(int argc,
Code::Flags flags =
Code::ComputeFlags(kind, DEBUG_PREPARE_STEP_IN, Code::kNoExtraICState,
NORMAL, argc);
- Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
+ Handle<UnseededNumberDictionary> cache =
+ isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
diff --git a/deps/v8/src/type-info.cc b/deps/v8/src/type-info.cc
index 790d77cb19..fcdc6108fe 100644
--- a/deps/v8/src/type-info.cc
+++ b/deps/v8/src/type-info.cc
@@ -71,7 +71,7 @@ TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) {
int entry = dictionary_->FindEntry(ast_id);
- return entry != NumberDictionary::kNotFound
+ return entry != UnseededNumberDictionary::kNotFound
? Handle<Object>(dictionary_->ValueAt(entry))
: Handle<Object>::cast(isolate_->factory()->undefined_value());
}
@@ -559,7 +559,7 @@ void TypeFeedbackOracle::CreateDictionary(Handle<Code> code,
ZoneList<RelocInfo>* infos) {
DisableAssertNoAllocation allocation_allowed;
byte* old_start = code->instruction_start();
- dictionary_ = FACTORY->NewNumberDictionary(infos->length());
+ dictionary_ = FACTORY->NewUnseededNumberDictionary(infos->length());
byte* new_start = code->instruction_start();
RelocateRelocInfos(infos, old_start, new_start);
}
@@ -639,7 +639,7 @@ void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) {
- ASSERT(dictionary_->FindEntry(ast_id) == NumberDictionary::kNotFound);
+ ASSERT(dictionary_->FindEntry(ast_id) == UnseededNumberDictionary::kNotFound);
MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target);
USE(maybe_result);
#ifdef DEBUG
diff --git a/deps/v8/src/type-info.h b/deps/v8/src/type-info.h
index 1519fcabb4..9d3080abbf 100644
--- a/deps/v8/src/type-info.h
+++ b/deps/v8/src/type-info.h
@@ -303,7 +303,7 @@ class TypeFeedbackOracle BASE_EMBEDDED {
Handle<Context> global_context_;
Isolate* isolate_;
- Handle<NumberDictionary> dictionary_;
+ Handle<UnseededNumberDictionary> dictionary_;
DISALLOW_COPY_AND_ASSIGN(TypeFeedbackOracle);
};
diff --git a/deps/v8/src/utils.h b/deps/v8/src/utils.h
index 68b1517de4..17bf06ffa3 100644
--- a/deps/v8/src/utils.h
+++ b/deps/v8/src/utils.h
@@ -252,10 +252,13 @@ class BitField {
// ----------------------------------------------------------------------------
// Hash function.
+static const uint32_t kZeroHashSeed = 0;
+
// Thomas Wang, Integer Hash Functions.
// http://www.concentric.net/~Ttwang/tech/inthash.htm
-inline uint32_t ComputeIntegerHash(uint32_t key) {
+inline uint32_t ComputeIntegerHash(uint32_t key, uint32_t seed) {
uint32_t hash = key;
+ hash = hash ^ seed;
hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1;
hash = hash ^ (hash >> 12);
hash = hash + (hash << 2);
@@ -280,7 +283,8 @@ inline uint32_t ComputeLongHash(uint64_t key) {
inline uint32_t ComputePointerHash(void* ptr) {
return ComputeIntegerHash(
- static_cast<uint32_t>(reinterpret_cast<intptr_t>(ptr)));
+ static_cast<uint32_t>(reinterpret_cast<intptr_t>(ptr)),
+ v8::internal::kZeroHashSeed);
}
diff --git a/deps/v8/src/v8.cc b/deps/v8/src/v8.cc
index c882d86f8d..36ee221948 100644
--- a/deps/v8/src/v8.cc
+++ b/deps/v8/src/v8.cc
@@ -47,7 +47,7 @@ static Mutex* init_once_mutex = OS::CreateMutex();
static bool init_once_called = false;
bool V8::is_running_ = false;
-bool V8::has_been_setup_ = false;
+bool V8::has_been_set_up_ = false;
bool V8::has_been_disposed_ = false;
bool V8::has_fatal_error_ = false;
bool V8::use_crankshaft_ = true;
@@ -82,7 +82,7 @@ bool V8::Initialize(Deserializer* des) {
if (isolate->IsInitialized()) return true;
is_running_ = true;
- has_been_setup_ = true;
+ has_been_set_up_ = true;
has_fatal_error_ = false;
has_been_disposed_ = false;
@@ -100,7 +100,7 @@ void V8::TearDown() {
Isolate* isolate = Isolate::Current();
ASSERT(isolate->IsDefaultIsolate());
- if (!has_been_setup_ || has_been_disposed_) return;
+ if (!has_been_set_up_ || has_been_disposed_) return;
isolate->TearDown();
is_running_ = false;
@@ -239,8 +239,8 @@ void V8::InitializeOncePerProcess() {
if (init_once_called) return;
init_once_called = true;
- // Setup the platform OS support.
- OS::Setup();
+ // Set up the platform OS support.
+ OS::SetUp();
use_crankshaft_ = FLAG_crankshaft;
@@ -248,7 +248,7 @@ void V8::InitializeOncePerProcess() {
use_crankshaft_ = false;
}
- CPU::Setup();
+ CPU::SetUp();
if (!CPU::SupportsCrankshaft()) {
use_crankshaft_ = false;
}
diff --git a/deps/v8/src/v8.h b/deps/v8/src/v8.h
index b9a3e05386..adfdb3ea88 100644
--- a/deps/v8/src/v8.h
+++ b/deps/v8/src/v8.h
@@ -118,7 +118,7 @@ class V8 : public AllStatic {
// True if engine is currently running
static bool is_running_;
// True if V8 has ever been run
- static bool has_been_setup_;
+ static bool has_been_set_up_;
// True if error has been signaled for current engine
// (reset to false if engine is restarted)
static bool has_fatal_error_;
diff --git a/deps/v8/src/v8globals.h b/deps/v8/src/v8globals.h
index 005cdbdaec..bdb960e8fd 100644
--- a/deps/v8/src/v8globals.h
+++ b/deps/v8/src/v8globals.h
@@ -130,7 +130,8 @@ class FixedArray;
class FunctionLiteral;
class FunctionTemplateInfo;
class MemoryChunk;
-class NumberDictionary;
+class SeededNumberDictionary;
+class UnseededNumberDictionary;
class StringDictionary;
template <typename T> class Handle;
class Heap;
diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc
index 617b7d1c50..95535851d1 100644
--- a/deps/v8/src/version.cc
+++ b/deps/v8/src/version.cc
@@ -34,7 +34,7 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 3
#define MINOR_VERSION 8
-#define BUILD_NUMBER 5
+#define BUILD_NUMBER 6
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/deps/v8/src/win32-headers.h b/deps/v8/src/win32-headers.h
index 0ee330668a..ca1b1d8b8e 100644
--- a/deps/v8/src/win32-headers.h
+++ b/deps/v8/src/win32-headers.h
@@ -75,7 +75,9 @@
// makes it impossible to have them elsewhere.
#include <winsock2.h>
#include <ws2tcpip.h>
+#ifndef __MINGW32__
#include <wspiapi.h>
+#endif // __MINGW32__
#include <process.h> // for _beginthreadex()
#include <stdlib.h>
#endif // V8_WIN32_HEADERS_FULL
diff --git a/deps/v8/src/x64/assembler-x64-inl.h b/deps/v8/src/x64/assembler-x64-inl.h
index ab387d6d0a..141d092d8e 100644
--- a/deps/v8/src/x64/assembler-x64-inl.h
+++ b/deps/v8/src/x64/assembler-x64-inl.h
@@ -262,7 +262,7 @@ Object* RelocInfo::target_object() {
}
-Handle<Object> RelocInfo::target_object_handle(Assembler *origin) {
+Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
if (rmode_ == EMBEDDED_OBJECT) {
return Memory::Object_Handle_at(pc_);
diff --git a/deps/v8/src/x64/assembler-x64.cc b/deps/v8/src/x64/assembler-x64.cc
index ca3bece5f0..eb8d7d4d99 100644
--- a/deps/v8/src/x64/assembler-x64.cc
+++ b/deps/v8/src/x64/assembler-x64.cc
@@ -383,7 +383,7 @@ Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
}
#endif
- // Setup buffer pointers.
+ // Set up buffer pointers.
ASSERT(buffer_ != NULL);
pc_ = buffer_;
reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
@@ -412,7 +412,7 @@ void Assembler::GetCode(CodeDesc* desc) {
// Finalize code (at this point overflow() may be true, but the gap ensures
// that we are still not overlapping instructions and relocation info).
ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
- // Setup code descriptor.
+ // Set up code descriptor.
desc->buffer = buffer_;
desc->buffer_size = buffer_size_;
desc->instr_size = pc_offset();
@@ -502,7 +502,7 @@ void Assembler::GrowBuffer() {
V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
}
- // Setup new buffer.
+ // Set up new buffer.
desc.buffer = NewArray<byte>(desc.buffer_size);
desc.instr_size = pc_offset();
desc.reloc_size =
diff --git a/deps/v8/src/x64/builtins-x64.cc b/deps/v8/src/x64/builtins-x64.cc
index ef63c7a27b..4833e03c8e 100644
--- a/deps/v8/src/x64/builtins-x64.cc
+++ b/deps/v8/src/x64/builtins-x64.cc
@@ -337,7 +337,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
__ push(rbx);
__ push(rbx);
- // Setup pointer to last argument.
+ // Set up pointer to last argument.
__ lea(rbx, Operand(rbp, StandardFrameConstants::kCallerSPOffset));
// Copy arguments and receiver to the expression stack.
@@ -1198,7 +1198,7 @@ static void AllocateJSArray(MacroAssembler* masm,
// Both registers are preserved by this code so no need to differentiate between
// a construct call and a normal call.
static void ArrayNativeCode(MacroAssembler* masm,
- Label *call_generic_code) {
+ Label* call_generic_code) {
Label argc_one_or_more, argc_two_or_more, empty_array, not_empty_array,
has_non_smi_element;
diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc
index ea9c494e8a..03a5170bae 100644
--- a/deps/v8/src/x64/code-stubs-x64.cc
+++ b/deps/v8/src/x64/code-stubs-x64.cc
@@ -124,12 +124,12 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
// Get the function from the stack.
__ movq(rcx, Operand(rsp, 1 * kPointerSize));
- // Setup the object header.
+ // Set up the object header.
__ LoadRoot(kScratchRegister, Heap::kFunctionContextMapRootIndex);
__ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister);
__ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length));
- // Setup the fixed slots.
+ // Set up the fixed slots.
__ Set(rbx, 0); // Set to NULL.
__ movq(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx);
__ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rsi);
@@ -173,7 +173,7 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
// Get the serialized scope info from the stack.
__ movq(rbx, Operand(rsp, 2 * kPointerSize));
- // Setup the object header.
+ // Set up the object header.
__ LoadRoot(kScratchRegister, Heap::kBlockContextMapRootIndex);
__ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister);
__ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length));
@@ -194,7 +194,7 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
__ movq(rcx, ContextOperand(rcx, Context::CLOSURE_INDEX));
__ bind(&after_sentinel);
- // Setup the fixed slots.
+ // Set up the fixed slots.
__ movq(ContextOperand(rax, Context::CLOSURE_INDEX), rcx);
__ movq(ContextOperand(rax, Context::PREVIOUS_INDEX), rsi);
__ movq(ContextOperand(rax, Context::EXTENSION_INDEX), rbx);
@@ -2399,7 +2399,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
__ movq(FieldOperand(rax, i), rdx);
}
- // Setup the callee in-object property.
+ // Set up the callee in-object property.
STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
__ movq(rdx, Operand(rsp, 3 * kPointerSize));
__ movq(FieldOperand(rax, JSObject::kHeaderSize +
@@ -2414,7 +2414,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
Heap::kArgumentsLengthIndex * kPointerSize),
rcx);
- // Setup the elements pointer in the allocated arguments object.
+ // Set up the elements pointer in the allocated arguments object.
// If we allocated a parameter map, edi will point there, otherwise to the
// backing store.
__ lea(rdi, Operand(rax, Heap::kArgumentsObjectSize));
@@ -2621,7 +2621,7 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Get the parameters pointer from the stack.
__ movq(rdx, Operand(rsp, 2 * kPointerSize));
- // Setup the elements pointer in the allocated arguments object and
+ // Set up the elements pointer in the allocated arguments object and
// initialize the header in the elements fixed array.
__ lea(rdi, Operand(rax, Heap::kArgumentsObjectSizeStrict));
__ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi);
@@ -3942,7 +3942,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
Label not_outermost_js, not_outermost_js_2;
{ // NOLINT. Scope block confuses linter.
MacroAssembler::NoRootArrayScope uninitialized_root_register(masm);
- // Setup frame.
+ // Set up frame.
__ push(rbp);
__ movq(rbp, rsp);
@@ -4156,12 +4156,14 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
// Get return address and delta to inlined map check.
__ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
__ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
- __ movq(Operand(kScratchRegister, kOffsetToMapCheckValue), rax);
if (FLAG_debug_code) {
__ movl(rdi, Immediate(kWordBeforeMapCheckValue));
__ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), rdi);
__ Assert(equal, "InstanceofStub unexpected call site cache (check).");
}
+ __ movq(kScratchRegister,
+ Operand(kScratchRegister, kOffsetToMapCheckValue));
+ __ movq(Operand(kScratchRegister, 0), rax);
}
__ movq(rcx, FieldOperand(rax, Map::kPrototypeOffset));
@@ -4959,7 +4961,7 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
Register character,
Register scratch) {
// hash = (seed + character) + ((seed + character) << 10);
- __ LoadRoot(scratch, Heap::kStringHashSeedRootIndex);
+ __ LoadRoot(scratch, Heap::kHashSeedRootIndex);
__ SmiToInteger32(scratch, scratch);
__ addl(scratch, character);
__ movl(hash, scratch);
@@ -5003,13 +5005,12 @@ void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
__ shll(scratch, Immediate(15));
__ addl(hash, scratch);
- uint32_t kHashShiftCutOffMask = (1 << (32 - String::kHashShift)) - 1;
- __ andl(hash, Immediate(kHashShiftCutOffMask));
+ __ andl(hash, Immediate(String::kHashBitMask));
// if (hash == 0) hash = 27;
Label hash_not_zero;
__ j(not_zero, &hash_not_zero);
- __ Set(hash, 27);
+ __ Set(hash, StringHasher::kZeroHash);
__ bind(&hash_not_zero);
}
@@ -5080,7 +5081,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
__ ret(3 * kPointerSize);
__ bind(&make_two_character_string);
- // Setup registers for allocating the two character string.
+ // Set up registers for allocating the two character string.
__ movzxwq(rbx, FieldOperand(rax, rdx, times_1, SeqAsciiString::kHeaderSize));
__ AllocateAsciiString(rax, rcx, r11, r14, r15, &runtime);
__ movw(FieldOperand(rax, SeqAsciiString::kHeaderSize), rbx);
diff --git a/deps/v8/src/x64/cpu-x64.cc b/deps/v8/src/x64/cpu-x64.cc
index ae5045f0df..69e77eee9d 100644
--- a/deps/v8/src/x64/cpu-x64.cc
+++ b/deps/v8/src/x64/cpu-x64.cc
@@ -41,7 +41,7 @@
namespace v8 {
namespace internal {
-void CPU::Setup() {
+void CPU::SetUp() {
CpuFeatures::Probe();
}
diff --git a/deps/v8/src/x64/deoptimizer-x64.cc b/deps/v8/src/x64/deoptimizer-x64.cc
index d684ad713f..a5a171a2a8 100644
--- a/deps/v8/src/x64/deoptimizer-x64.cc
+++ b/deps/v8/src/x64/deoptimizer-x64.cc
@@ -314,7 +314,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
output_[0] = input_;
output_[0]->SetPc(reinterpret_cast<intptr_t>(from_));
} else {
- // Setup the frame pointer and the context pointer.
+ // Set up the frame pointer and the context pointer.
output_[0]->SetRegister(rbp.code(), input_->GetRegister(rbp.code()));
output_[0]->SetRegister(rsi.code(), input_->GetRegister(rsi.code()));
diff --git a/deps/v8/src/x64/full-codegen-x64.cc b/deps/v8/src/x64/full-codegen-x64.cc
index 24df20ba76..eeef0e94e8 100644
--- a/deps/v8/src/x64/full-codegen-x64.cc
+++ b/deps/v8/src/x64/full-codegen-x64.cc
@@ -967,7 +967,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ movq(rcx, FieldOperand(rcx, DescriptorArray::kEnumerationIndexOffset));
__ movq(rdx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset));
- // Setup the four remaining stack slots.
+ // Set up the four remaining stack slots.
__ push(rax); // Map.
__ push(rdx); // Enumeration cache.
__ movq(rax, FieldOperand(rdx, FixedArray::kLengthOffset));
diff --git a/deps/v8/src/x64/lithium-codegen-x64.cc b/deps/v8/src/x64/lithium-codegen-x64.cc
index 6239acb515..392c74dc23 100644
--- a/deps/v8/src/x64/lithium-codegen-x64.cc
+++ b/deps/v8/src/x64/lithium-codegen-x64.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -1755,13 +1755,17 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
// Branches to a label or falls through with the answer in the z flag.
-// Trashes the temp register and possibly input (if it and temp are aliased).
+// Trashes the temp register.
void LCodeGen::EmitClassOfTest(Label* is_true,
Label* is_false,
Handle<String> class_name,
Register input,
Register temp,
- Register scratch) {
+ Register temp2) {
+ ASSERT(!input.is(temp));
+ ASSERT(!input.is(temp2));
+ ASSERT(!temp.is(temp2));
+
__ JumpIfSmi(input, is_false);
if (class_name->IsEqualTo(CStrVector("Function"))) {
@@ -1782,9 +1786,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
// Faster code path to avoid two compares: subtract lower bound from the
// actual type and do a signed compare with the width of the type range.
__ movq(temp, FieldOperand(input, HeapObject::kMapOffset));
- __ movq(scratch, FieldOperand(temp, Map::kInstanceTypeOffset));
- __ subb(scratch, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
- __ cmpb(scratch,
+ __ movq(temp2, FieldOperand(temp, Map::kInstanceTypeOffset));
+ __ subb(temp2, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
+ __ cmpb(temp2,
Immediate(static_cast<int8_t>(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)));
__ j(above, is_false);
@@ -1897,9 +1901,10 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
Register map = ToRegister(instr->TempAt(0));
__ movq(map, FieldOperand(object, HeapObject::kMapOffset));
__ bind(deferred->map_check()); // Label for calculating code patching.
- __ movq(kScratchRegister, factory()->the_hole_value(),
- RelocInfo::EMBEDDED_OBJECT);
- __ cmpq(map, kScratchRegister); // Patched to cached map.
+ Handle<JSGlobalPropertyCell> cache_cell =
+ factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
+ __ movq(kScratchRegister, cache_cell, RelocInfo::GLOBAL_PROPERTY_CELL);
+ __ cmpq(map, Operand(kScratchRegister, 0));
__ j(not_equal, &cache_miss, Label::kNear);
// Patched to load either true or false.
__ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
@@ -2636,7 +2641,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
__ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset));
}
- // Setup deoptimization.
+ // Set up deoptimization.
RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
// Restore context.
@@ -2926,6 +2931,38 @@ void LCodeGen::DoPower(LPower* instr) {
}
+void LCodeGen::DoRandom(LRandom* instr) {
+ // Having marked this instruction as a call we can use any
+ // registers.
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+
+ // Choose the right register for the first argument depending on
+ // calling convention.
+#ifdef _WIN64
+ ASSERT(ToRegister(instr->InputAt(0)).is(rcx));
+ Register global_object = rcx;
+#else
+ ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
+ Register global_object = rdi;
+#endif
+
+ __ PrepareCallCFunction(1);
+ __ movq(global_object,
+ FieldOperand(global_object, GlobalObject::kGlobalContextOffset));
+ __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
+
+ // Convert 32 random bits in rax to 0.(32 random bits) in a double
+ // by computing:
+ // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
+ __ movl(rcx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
+ __ movd(xmm2, rcx);
+ __ movd(xmm1, rax);
+ __ cvtss2sd(xmm2, xmm2);
+ __ xorps(xmm1, xmm2);
+ __ subsd(xmm1, xmm2);
+}
+
+
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
TranscendentalCacheStub stub(TranscendentalCache::LOG,
@@ -3510,6 +3547,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
void LCodeGen::EmitNumberUntagD(Register input_reg,
XMMRegister result_reg,
bool deoptimize_on_undefined,
+ bool deoptimize_on_minus_zero,
LEnvironment* env) {
Label load_smi, done;
@@ -3537,6 +3575,15 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
}
// Heap number to XMM conversion.
__ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
+ if (deoptimize_on_minus_zero) {
+ XMMRegister xmm_scratch = xmm0;
+ __ xorps(xmm_scratch, xmm_scratch);
+ __ ucomisd(xmm_scratch, result_reg);
+ __ j(not_equal, &done, Label::kNear);
+ __ movmskpd(kScratchRegister, result_reg);
+ __ testq(kScratchRegister, Immediate(1));
+ DeoptimizeIf(not_zero, env);
+ }
__ jmp(&done, Label::kNear);
// Smi to XMM conversion
@@ -3628,6 +3675,7 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
EmitNumberUntagD(input_reg, result_reg,
instr->hydrogen()->deoptimize_on_undefined(),
+ instr->hydrogen()->deoptimize_on_minus_zero(),
instr->environment());
}
@@ -3747,13 +3795,23 @@ void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
}
+void LCodeGen::DoCheckMapCommon(Register reg,
+ Handle<Map> map,
+ CompareMapMode mode,
+ LEnvironment* env) {
+ Label success;
+ __ CompareMap(reg, map, &success, mode);
+ DeoptimizeIf(not_equal, env);
+ __ bind(&success);
+}
+
+
void LCodeGen::DoCheckMap(LCheckMap* instr) {
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
- __ Cmp(FieldOperand(reg, HeapObject::kMapOffset),
- instr->hydrogen()->map());
- DeoptimizeIf(not_equal, instr->environment());
+ Handle<Map> map = instr->hydrogen()->map();
+ DoCheckMapCommon(reg, map, instr->hydrogen()->mode(), instr->environment());
}
@@ -3819,9 +3877,8 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
// Check prototype maps up to the holder.
while (!current_prototype.is_identical_to(holder)) {
- __ Cmp(FieldOperand(reg, HeapObject::kMapOffset),
- Handle<Map>(current_prototype->map()));
- DeoptimizeIf(not_equal, instr->environment());
+ DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()),
+ ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
current_prototype =
Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
// Load next prototype object.
@@ -3829,9 +3886,8 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
}
// Check the holder map.
- __ Cmp(FieldOperand(reg, HeapObject::kMapOffset),
- Handle<Map>(current_prototype->map()));
- DeoptimizeIf(not_equal, instr->environment());
+ DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()),
+ ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
}
@@ -3855,7 +3911,7 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
DeoptimizeIf(not_equal, instr->environment());
}
- // Setup the parameters to the stub/runtime call.
+ // Set up the parameters to the stub/runtime call.
__ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(rax, JSFunction::kLiteralsOffset));
__ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
@@ -3956,7 +4012,7 @@ void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) {
Handle<FixedArray> constant_properties =
instr->hydrogen()->constant_properties();
- // Setup the parameters to the stub/runtime call.
+ // Set up the parameters to the stub/runtime call.
__ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(rax, JSFunction::kLiteralsOffset));
__ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
diff --git a/deps/v8/src/x64/lithium-codegen-x64.h b/deps/v8/src/x64/lithium-codegen-x64.h
index 832942f1ef..2890c530b7 100644
--- a/deps/v8/src/x64/lithium-codegen-x64.h
+++ b/deps/v8/src/x64/lithium-codegen-x64.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -102,7 +102,10 @@ class LCodeGen BASE_EMBEDDED {
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
Label* map_check);
- // Parallel move support.
+ void DoCheckMapCommon(Register reg, Handle<Map> map,
+ CompareMapMode mode, LEnvironment* env);
+
+// Parallel move support.
void DoParallelMove(LParallelMove* move);
void DoGap(LGap* instr);
@@ -252,6 +255,7 @@ class LCodeGen BASE_EMBEDDED {
void EmitNumberUntagD(Register input,
XMMRegister result,
bool deoptimize_on_undefined,
+ bool deoptimize_on_minus_zero,
LEnvironment* env);
// Emits optimized code for typeof x == "y". Modifies input register.
@@ -372,7 +376,7 @@ class LDeferredCode: public ZoneObject {
virtual void Generate() = 0;
virtual LInstruction* instr() = 0;
- void SetExit(Label *exit) { external_exit_ = exit; }
+ void SetExit(Label* exit) { external_exit_ = exit; }
Label* entry() { return &entry_; }
Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
int instruction_index() const { return instruction_index_; }
diff --git a/deps/v8/src/x64/lithium-x64.cc b/deps/v8/src/x64/lithium-x64.cc
index 5bae14bfa9..fee2f4f2ab 100644
--- a/deps/v8/src/x64/lithium-x64.cc
+++ b/deps/v8/src/x64/lithium-x64.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -1033,16 +1033,25 @@ LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
- HValue* v = instr->value();
- if (v->EmitAtUses()) {
- ASSERT(v->IsConstant());
- ASSERT(!v->representation().IsDouble());
- HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
+ HValue* value = instr->value();
+ if (value->EmitAtUses()) {
+ ASSERT(value->IsConstant());
+ ASSERT(!value->representation().IsDouble());
+ HBasicBlock* successor = HConstant::cast(value)->ToBoolean()
? instr->FirstSuccessor()
: instr->SecondSuccessor();
return new LGoto(successor->block_id());
}
- return AssignEnvironment(new LBranch(UseRegister(v)));
+
+ LBranch* result = new LBranch(UseRegister(value));
+ // Tagged values that are not known smis or booleans require a
+ // deoptimization environment.
+ Representation rep = value->representation();
+ HType type = value->type();
+ if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean()) {
+ return AssignEnvironment(result);
+ }
+ return result;
}
@@ -1329,7 +1338,11 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
LOperand* right = UseOrConstant(instr->MostConstantOperand());
LMulI* mul = new LMulI(left, right);
- return AssignEnvironment(DefineSameAsFirst(mul));
+ if (instr->CheckFlag(HValue::kCanOverflow) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ AssignEnvironment(mul);
+ }
+ return DefineSameAsFirst(mul);
} else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::MUL, instr);
} else {
@@ -1402,6 +1415,19 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
}
+LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
+ ASSERT(instr->representation().IsDouble());
+ ASSERT(instr->global_object()->representation().IsTagged());
+#ifdef _WIN64
+ LOperand* global_object = UseFixed(instr->global_object(), rcx);
+#else
+ LOperand* global_object = UseFixed(instr->global_object(), rdi);
+#endif
+ LRandom* result = new LRandom(global_object);
+ return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
+}
+
+
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
ASSERT(instr->left()->representation().IsTagged());
ASSERT(instr->right()->representation().IsTagged());
@@ -1525,7 +1551,7 @@ LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
HClassOfTestAndBranch* instr) {
- return new LClassOfTestAndBranch(UseTempRegister(instr->value()),
+ return new LClassOfTestAndBranch(UseRegister(instr->value()),
TempRegister(),
TempRegister());
}
@@ -1553,7 +1579,7 @@ LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
LOperand* object = UseRegister(instr->value());
LValueOf* result = new LValueOf(object);
- return AssignEnvironment(DefineSameAsFirst(result));
+ return DefineSameAsFirst(result);
}
@@ -1866,7 +1892,8 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
- return AssignEnvironment(DefineAsRegister(result));
+ if (instr->RequiresHoleCheck()) AssignEnvironment(result);
+ return DefineAsRegister(result);
}
diff --git a/deps/v8/src/x64/lithium-x64.h b/deps/v8/src/x64/lithium-x64.h
index c6fcfeb81e..193f0389da 100644
--- a/deps/v8/src/x64/lithium-x64.h
+++ b/deps/v8/src/x64/lithium-x64.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -141,6 +141,7 @@ class LCodeGen;
V(Parameter) \
V(Power) \
V(PushArgument) \
+ V(Random) \
V(RegExpLiteral) \
V(Return) \
V(ShiftI) \
@@ -1024,6 +1025,17 @@ class LPower: public LTemplateInstruction<1, 2, 0> {
};
+class LRandom: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LRandom(LOperand* global_object) {
+ inputs_[0] = global_object;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Random, "random")
+ DECLARE_HYDROGEN_ACCESSOR(Random)
+};
+
+
class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
public:
LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
diff --git a/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc
index 10e423b5b9..47553697ae 100644
--- a/deps/v8/src/x64/macro-assembler-x64.cc
+++ b/deps/v8/src/x64/macro-assembler-x64.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -495,7 +495,7 @@ void MacroAssembler::Abort(const char* msg) {
// from the real pointer as a smi.
intptr_t p1 = reinterpret_cast<intptr_t>(msg);
intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
- // Note: p0 might not be a valid Smi *value*, but it has a valid Smi tag.
+ // Note: p0 might not be a valid Smi _value_, but it has a valid Smi tag.
ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
#ifdef DEBUG
if (msg != NULL) {
@@ -2739,15 +2739,48 @@ void MacroAssembler::StoreNumberToDoubleElements(
}
+void MacroAssembler::CompareMap(Register obj,
+ Handle<Map> map,
+ Label* early_success,
+ CompareMapMode mode) {
+ Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
+ if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
+ Map* transitioned_fast_element_map(
+ map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL));
+ ASSERT(transitioned_fast_element_map == NULL ||
+ map->elements_kind() != FAST_ELEMENTS);
+ if (transitioned_fast_element_map != NULL) {
+ j(equal, early_success, Label::kNear);
+ Cmp(FieldOperand(obj, HeapObject::kMapOffset),
+ Handle<Map>(transitioned_fast_element_map));
+ }
+
+ Map* transitioned_double_map(
+ map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL));
+ ASSERT(transitioned_double_map == NULL ||
+ map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
+ if (transitioned_double_map != NULL) {
+ j(equal, early_success, Label::kNear);
+ Cmp(FieldOperand(obj, HeapObject::kMapOffset),
+ Handle<Map>(transitioned_double_map));
+ }
+ }
+}
+
+
void MacroAssembler::CheckMap(Register obj,
Handle<Map> map,
Label* fail,
- SmiCheckType smi_check_type) {
+ SmiCheckType smi_check_type,
+ CompareMapMode mode) {
if (smi_check_type == DO_SMI_CHECK) {
JumpIfSmi(obj, fail);
}
- Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
+
+ Label success;
+ CompareMap(obj, map, &success, mode);
j(not_equal, fail);
+ bind(&success);
}
@@ -3198,7 +3231,7 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
void MacroAssembler::EnterExitFramePrologue(bool save_rax) {
- // Setup the frame structure on the stack.
+ // Set up the frame structure on the stack.
// All constants are relative to the frame pointer of the exit frame.
ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize);
ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize);
@@ -3258,7 +3291,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) {
EnterExitFramePrologue(true);
- // Setup argv in callee-saved register r15. It is reused in LeaveExitFrame,
+ // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame,
// so it must be retained across the C-call.
int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
lea(r15, Operand(rbp, r14, times_pointer_size, offset));
@@ -3386,6 +3419,42 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
}
+void MacroAssembler::GetNumberHash(Register r0, Register scratch) {
+ // First of all we assign the hash seed to scratch.
+ LoadRoot(scratch, Heap::kHashSeedRootIndex);
+ SmiToInteger32(scratch, scratch);
+
+ // Xor original key with a seed.
+ xorl(r0, scratch);
+
+ // Compute the hash code from the untagged key. This must be kept in sync
+ // with ComputeIntegerHash in utils.h.
+ //
+ // hash = ~hash + (hash << 15);
+ movl(scratch, r0);
+ notl(r0);
+ shll(scratch, Immediate(15));
+ addl(r0, scratch);
+ // hash = hash ^ (hash >> 12);
+ movl(scratch, r0);
+ shrl(scratch, Immediate(12));
+ xorl(r0, scratch);
+ // hash = hash + (hash << 2);
+ leal(r0, Operand(r0, r0, times_4, 0));
+ // hash = hash ^ (hash >> 4);
+ movl(scratch, r0);
+ shrl(scratch, Immediate(4));
+ xorl(r0, scratch);
+ // hash = hash * 2057;
+ imull(r0, r0, Immediate(2057));
+ // hash = hash ^ (hash >> 16);
+ movl(scratch, r0);
+ shrl(scratch, Immediate(16));
+ xorl(r0, scratch);
+}
+
+
+
void MacroAssembler::LoadFromNumberDictionary(Label* miss,
Register elements,
Register key,
@@ -3416,34 +3485,11 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
Label done;
- // Compute the hash code from the untagged key. This must be kept in sync
- // with ComputeIntegerHash in utils.h.
- //
- // hash = ~hash + (hash << 15);
- movl(r1, r0);
- notl(r0);
- shll(r1, Immediate(15));
- addl(r0, r1);
- // hash = hash ^ (hash >> 12);
- movl(r1, r0);
- shrl(r1, Immediate(12));
- xorl(r0, r1);
- // hash = hash + (hash << 2);
- leal(r0, Operand(r0, r0, times_4, 0));
- // hash = hash ^ (hash >> 4);
- movl(r1, r0);
- shrl(r1, Immediate(4));
- xorl(r0, r1);
- // hash = hash * 2057;
- imull(r0, r0, Immediate(2057));
- // hash = hash ^ (hash >> 16);
- movl(r1, r0);
- shrl(r1, Immediate(16));
- xorl(r0, r1);
+ GetNumberHash(r0, r1);
// Compute capacity mask.
- SmiToInteger32(r1,
- FieldOperand(elements, NumberDictionary::kCapacityOffset));
+ SmiToInteger32(r1, FieldOperand(elements,
+ SeededNumberDictionary::kCapacityOffset));
decl(r1);
// Generate an unrolled loop that performs a few probes before giving up.
@@ -3453,19 +3499,19 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
movq(r2, r0);
// Compute the masked index: (hash + i + i * i) & mask.
if (i > 0) {
- addl(r2, Immediate(NumberDictionary::GetProbeOffset(i)));
+ addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i)));
}
and_(r2, r1);
// Scale the index by multiplying by the entry size.
- ASSERT(NumberDictionary::kEntrySize == 3);
+ ASSERT(SeededNumberDictionary::kEntrySize == 3);
lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3
// Check if the key matches.
cmpq(key, FieldOperand(elements,
r2,
times_pointer_size,
- NumberDictionary::kElementsStartOffset));
+ SeededNumberDictionary::kElementsStartOffset));
if (i != (kProbes - 1)) {
j(equal, &done);
} else {
@@ -3476,7 +3522,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
bind(&done);
// Check that the value is a normal propety.
const int kDetailsOffset =
- NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
+ SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
ASSERT_EQ(NORMAL, 0);
Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
Smi::FromInt(PropertyDetails::TypeField::kMask));
@@ -3484,7 +3530,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
// Get the value at the masked, scaled index.
const int kValueOffset =
- NumberDictionary::kElementsStartOffset + kPointerSize;
+ SeededNumberDictionary::kElementsStartOffset + kPointerSize;
movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
}
diff --git a/deps/v8/src/x64/macro-assembler-x64.h b/deps/v8/src/x64/macro-assembler-x64.h
index 97a98017c5..8596852db4 100644
--- a/deps/v8/src/x64/macro-assembler-x64.h
+++ b/deps/v8/src/x64/macro-assembler-x64.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -328,7 +328,7 @@ class MacroAssembler: public Assembler {
// ---------------------------------------------------------------------------
// JavaScript invokes
- // Setup call kind marking in rcx. The method takes rcx as an
+ // Set up call kind marking in rcx. The method takes rcx as an
// explicit first parameter to make the code more readable at the
// call sites.
void SetCallKind(Register dst, CallKind kind);
@@ -889,13 +889,24 @@ class MacroAssembler: public Assembler {
XMMRegister xmm_scratch,
Label* fail);
- // Check if the map of an object is equal to a specified map and
- // branch to label if not. Skip the smi check if not required
- // (object is known to be a heap object)
+ // Compare an object's map with the specified map and its transitioned
+ // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. FLAGS are set with
+ // result of map compare. If multiple map compares are required, the compare
+ // sequences branches to early_success.
+ void CompareMap(Register obj,
+ Handle<Map> map,
+ Label* early_success,
+ CompareMapMode mode = REQUIRE_EXACT_MAP);
+
+ // Check if the map of an object is equal to a specified map and branch to
+ // label if not. Skip the smi check if not required (object is known to be a
+ // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
+ // against maps that are ElementsKind transition maps of the specificed map.
void CheckMap(Register obj,
Handle<Map> map,
Label* fail,
- SmiCheckType smi_check_type);
+ SmiCheckType smi_check_type,
+ CompareMapMode mode = REQUIRE_EXACT_MAP);
// Check if the map of an object is equal to a specified map and branch to a
// specified target if equal. Skip the smi check if not required (object is
@@ -975,6 +986,7 @@ class MacroAssembler: public Assembler {
Register scratch,
Label* miss);
+ void GetNumberHash(Register r0, Register scratch);
void LoadFromNumberDictionary(Label* miss,
Register elements,
diff --git a/deps/v8/src/x64/stub-cache-x64.cc b/deps/v8/src/x64/stub-cache-x64.cc
index a28dbbf027..3633fbbcee 100644
--- a/deps/v8/src/x64/stub-cache-x64.cc
+++ b/deps/v8/src/x64/stub-cache-x64.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -691,13 +691,9 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
Register name_reg,
Register scratch,
Label* miss_label) {
- // Check that the object isn't a smi.
- __ JumpIfSmi(receiver_reg, miss_label);
-
// Check that the map of the object hasn't changed.
- __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset),
- Handle<Map>(object->map()));
- __ j(not_equal, miss_label);
+ __ CheckMap(receiver_reg, Handle<Map>(object->map()),
+ miss_label, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
@@ -864,12 +860,10 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
if (in_new_space) {
// Save the map in scratch1 for later.
__ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
- __ Cmp(scratch1, current_map);
- } else {
- __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), current_map);
}
- // Branch on the result of the map check.
- __ j(not_equal, miss);
+ __ CheckMap(reg, Handle<Map>(current_map),
+ miss, DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
+
// Check access rights to the global object. This has to happen after
// the map check so that we know that the object is actually a global
// object.
@@ -901,8 +895,8 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
// Check the holder map.
- __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map()));
- __ j(not_equal, miss);
+ __ CheckMap(reg, Handle<Map>(holder->map()),
+ miss, DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform security check for access to the global object.
ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
@@ -2187,7 +2181,7 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
__ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
}
- // Setup the context (function already in rdi).
+ // Set up the context (function already in rdi).
__ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
// Jump to the cached code (tail call).
@@ -2251,13 +2245,9 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
// -----------------------------------
Label miss;
- // Check that the object isn't a smi.
- __ JumpIfSmi(rdx, &miss);
-
// Check that the map of the object hasn't changed.
- __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
- Handle<Map>(object->map()));
- __ j(not_equal, &miss);
+ __ CheckMap(rdx, Handle<Map>(object->map()), &miss,
+ DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
@@ -2301,13 +2291,9 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
// -----------------------------------
Label miss;
- // Check that the object isn't a smi.
- __ JumpIfSmi(rdx, &miss);
-
// Check that the map of the object hasn't changed.
- __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
- Handle<Map>(receiver->map()));
- __ j(not_equal, &miss);
+ __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss,
+ DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
// Perform global security token check if needed.
if (receiver->IsJSGlobalProxy()) {
diff --git a/deps/v8/test/cctest/SConscript b/deps/v8/test/cctest/SConscript
index 5fc9188ee9..edb859e9cb 100644
--- a/deps/v8/test/cctest/SConscript
+++ b/deps/v8/test/cctest/SConscript
@@ -73,6 +73,7 @@ SOURCES = {
'test-fixed-dtoa.cc',
'test-flags.cc',
'test-func-name-inference.cc',
+ 'test-hashing.cc',
'test-hashmap.cc',
'test-heap-profiler.cc',
'test-heap.cc',
diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h
index c04d893c10..0b93562216 100644
--- a/deps/v8/test/cctest/cctest.h
+++ b/deps/v8/test/cctest/cctest.h
@@ -104,7 +104,7 @@ class ApiTestFuzzer: public v8::internal::Thread {
FOURTH_PART,
LAST_PART = FOURTH_PART };
- static void Setup(PartOfTest part);
+ static void SetUp(PartOfTest part);
static void RunAllTests();
static void TearDown();
// This method switches threads if we are running the Threading test.
diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc
index 899c9021ff..c654dfa8bb 100644
--- a/deps/v8/test/cctest/test-alloc.cc
+++ b/deps/v8/test/cctest/test-alloc.cc
@@ -203,10 +203,10 @@ class Block {
TEST(CodeRange) {
const int code_range_size = 32*MB;
- OS::Setup();
+ OS::SetUp();
Isolate::Current()->InitializeLoggingAndCounters();
CodeRange* code_range = new CodeRange(Isolate::Current());
- code_range->Setup(code_range_size);
+ code_range->SetUp(code_range_size);
int current_allocated = 0;
int total_allocated = 0;
List<Block> blocks(1000);
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index fb8becda38..d001e65263 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -2867,6 +2867,16 @@ THREADED_TEST(isNumberType) {
obj = env->Global()->Get(v8_str("obj"));
CHECK(!obj->IsInt32());
CHECK(!obj->IsUint32());
+ // Positive zero
+ CompileRun("var obj = 0.0;");
+ obj = env->Global()->Get(v8_str("obj"));
+ CHECK(obj->IsInt32());
+ CHECK(obj->IsUint32());
+ // Positive zero
+ CompileRun("var obj = -0.0;");
+ obj = env->Global()->Get(v8_str("obj"));
+ CHECK(!obj->IsInt32());
+ CHECK(!obj->IsUint32());
}
@@ -7941,7 +7951,7 @@ THREADED_TEST(CrossEval) {
other->SetSecurityToken(token);
current->SetSecurityToken(token);
- // Setup reference from current to other.
+ // Set up reference from current to other.
current->Global()->Set(v8_str("other"), other->Global());
// Check that new variables are introduced in other context.
@@ -8021,7 +8031,7 @@ THREADED_TEST(EvalInDetachedGlobal) {
v8::Persistent<Context> context0 = Context::New();
v8::Persistent<Context> context1 = Context::New();
- // Setup function in context0 that uses eval from context0.
+ // Set up function in context0 that uses eval from context0.
context0->Enter();
v8::Handle<v8::Value> fun =
CompileRun("var x = 42;"
@@ -8059,7 +8069,7 @@ THREADED_TEST(CrossLazyLoad) {
other->SetSecurityToken(token);
current->SetSecurityToken(token);
- // Setup reference from current to other.
+ // Set up reference from current to other.
current->Global()->Set(v8_str("other"), other->Global());
// Trigger lazy loading in other context.
@@ -10170,7 +10180,7 @@ void ApiTestFuzzer::Run() {
static unsigned linear_congruential_generator;
-void ApiTestFuzzer::Setup(PartOfTest part) {
+void ApiTestFuzzer::SetUp(PartOfTest part) {
linear_congruential_generator = i::FLAG_testing_prng_seed;
fuzzing_ = true;
int count = RegisterThreadedTest::count();
@@ -10234,25 +10244,25 @@ void ApiTestFuzzer::TearDown() {
// Lets not be needlessly self-referential.
TEST(Threading) {
- ApiTestFuzzer::Setup(ApiTestFuzzer::FIRST_PART);
+ ApiTestFuzzer::SetUp(ApiTestFuzzer::FIRST_PART);
ApiTestFuzzer::RunAllTests();
ApiTestFuzzer::TearDown();
}
TEST(Threading2) {
- ApiTestFuzzer::Setup(ApiTestFuzzer::SECOND_PART);
+ ApiTestFuzzer::SetUp(ApiTestFuzzer::SECOND_PART);
ApiTestFuzzer::RunAllTests();
ApiTestFuzzer::TearDown();
}
TEST(Threading3) {
- ApiTestFuzzer::Setup(ApiTestFuzzer::THIRD_PART);
+ ApiTestFuzzer::SetUp(ApiTestFuzzer::THIRD_PART);
ApiTestFuzzer::RunAllTests();
ApiTestFuzzer::TearDown();
}
TEST(Threading4) {
- ApiTestFuzzer::Setup(ApiTestFuzzer::FOURTH_PART);
+ ApiTestFuzzer::SetUp(ApiTestFuzzer::FOURTH_PART);
ApiTestFuzzer::RunAllTests();
ApiTestFuzzer::TearDown();
}
@@ -12111,7 +12121,7 @@ THREADED_TEST(GetCallingContext) {
callback_templ->GetFunction());
calling_context0->Exit();
- // Expose context0 in context1 and setup a function that calls the
+ // Expose context0 in context1 and set up a function that calls the
// callback function.
calling_context1->Enter();
calling_context1->Global()->Set(v8_str("context0"),
@@ -12269,18 +12279,18 @@ THREADED_TEST(PixelArray) {
i::Handle<i::Smi> value(i::Smi::FromInt(2));
i::Handle<i::Object> no_failure;
- no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
+ no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode);
ASSERT(!no_failure.is_null());
i::USE(no_failure);
CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
*value.location() = i::Smi::FromInt(256);
- no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
+ no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode);
ASSERT(!no_failure.is_null());
i::USE(no_failure);
CHECK_EQ(255,
i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
*value.location() = i::Smi::FromInt(-1);
- no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
+ no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode);
ASSERT(!no_failure.is_null());
i::USE(no_failure);
CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
@@ -13549,21 +13559,24 @@ THREADED_TEST(IdleNotification) {
// Test that idle notification can be handled and eventually returns true.
// This just checks the contract of the IdleNotification() function,
// and does not verify that it does reasonable work.
-THREADED_TEST(IdleNotificationWithHint) {
+TEST(IdleNotificationWithHint) {
v8::HandleScope scope;
LocalContext env;
- CompileRun("function binom(n, m) {"
- " var C = [[1]];"
- " for (var i = 1; i <= n; ++i) {"
- " C[i] = [1];"
- " for (var j = 1; j < i; ++j) {"
- " C[i][j] = C[i-1][j-1] + C[i-1][j];"
- " }"
- " C[i][i] = 1;"
- " }"
- " return C[n][m];"
- "};"
- "binom(1000, 500)");
+ {
+ i::AlwaysAllocateScope always_allocate;
+ CompileRun("function binom(n, m) {"
+ " var C = [[1]];"
+ " for (var i = 1; i <= n; ++i) {"
+ " C[i] = [1];"
+ " for (var j = 1; j < i; ++j) {"
+ " C[i][j] = C[i-1][j-1] + C[i-1][j];"
+ " }"
+ " C[i][i] = 1;"
+ " }"
+ " return C[n][m];"
+ "};"
+ "binom(1000, 500)");
+ }
bool rv = false;
intptr_t old_size = HEAP->SizeOfObjects();
bool no_idle_work = v8::V8::IdleNotification(10);
@@ -13665,6 +13678,59 @@ THREADED_TEST(GetHeapStatistics) {
}
+class VisitorImpl : public v8::ExternalResourceVisitor {
+ public:
+ VisitorImpl(TestResource* r1, TestResource* r2)
+ : resource1_(r1),
+ resource2_(r2),
+ found_resource1_(false),
+ found_resource2_(false) {}
+ virtual ~VisitorImpl() {}
+ virtual void VisitExternalString(v8::Handle<v8::String> string) {
+ if (!string->IsExternal()) {
+ CHECK(string->IsExternalAscii());
+ return;
+ }
+ v8::String::ExternalStringResource* resource =
+ string->GetExternalStringResource();
+ CHECK(resource);
+ if (resource1_ == resource) {
+ CHECK(!found_resource1_);
+ found_resource1_ = true;
+ }
+ if (resource2_ == resource) {
+ CHECK(!found_resource2_);
+ found_resource2_ = true;
+ }
+ }
+ void CheckVisitedResources() {
+ CHECK(found_resource1_);
+ CHECK(found_resource2_);
+ }
+
+ private:
+ v8::String::ExternalStringResource* resource1_;
+ v8::String::ExternalStringResource* resource2_;
+ bool found_resource1_;
+ bool found_resource2_;
+};
+
+TEST(VisitExternalStrings) {
+ v8::HandleScope scope;
+ LocalContext env;
+ const char* string = "Some string";
+ uint16_t* two_byte_string = AsciiToTwoByteString(string);
+ TestResource* resource1 = new TestResource(two_byte_string);
+ v8::Local<v8::String> string1 = v8::String::NewExternal(resource1);
+ TestResource* resource2 = new TestResource(two_byte_string);
+ v8::Local<v8::String> string2 = v8::String::NewExternal(resource2);
+
+ VisitorImpl visitor(resource1, resource2);
+ v8::V8::VisitExternalResources(&visitor);
+ visitor.CheckVisitedResources();
+}
+
+
static double DoubleFromBits(uint64_t value) {
double target;
memcpy(&target, &value, sizeof(target));
diff --git a/deps/v8/test/cctest/test-assembler-x64.cc b/deps/v8/test/cctest/test-assembler-x64.cc
index 959cf3fe52..d81923fa5c 100644
--- a/deps/v8/test/cctest/test-assembler-x64.cc
+++ b/deps/v8/test/cctest/test-assembler-x64.cc
@@ -99,7 +99,7 @@ static void InitializeVM() {
TEST(AssemblerX64ReturnOperation) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -121,7 +121,7 @@ TEST(AssemblerX64ReturnOperation) {
}
TEST(AssemblerX64StackOperations) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -153,7 +153,7 @@ TEST(AssemblerX64StackOperations) {
}
TEST(AssemblerX64ArithmeticOperations) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -175,7 +175,7 @@ TEST(AssemblerX64ArithmeticOperations) {
}
TEST(AssemblerX64ImulOperation) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -203,7 +203,7 @@ TEST(AssemblerX64ImulOperation) {
}
TEST(AssemblerX64MemoryOperands) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -237,7 +237,7 @@ TEST(AssemblerX64MemoryOperands) {
}
TEST(AssemblerX64ControlFlow) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -266,7 +266,7 @@ TEST(AssemblerX64ControlFlow) {
}
TEST(AssemblerX64LoopImmediates) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc
index f567a0f770..b10e6889ec 100644
--- a/deps/v8/test/cctest/test-cpu-profiler.cc
+++ b/deps/v8/test/cctest/test-cpu-profiler.cc
@@ -216,7 +216,7 @@ TEST(TickEvents) {
TEST(CrashIfStoppingLastNonExistentProfile) {
InitializeVM();
TestSetup test_setup;
- CpuProfiler::Setup();
+ CpuProfiler::SetUp();
CpuProfiler::StartProfiling("1");
CpuProfiler::StopProfiling("2");
CpuProfiler::StartProfiling("1");
@@ -268,7 +268,7 @@ TEST(Issue1398) {
TEST(DeleteAllCpuProfiles) {
InitializeVM();
TestSetup test_setup;
- CpuProfiler::Setup();
+ CpuProfiler::SetUp();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CpuProfiler::DeleteAllProfiles();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 8543a37720..4fa7afa099 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -2743,7 +2743,7 @@ TEST(DebugStepKeyedLoadLoop) {
v8::Handle<v8::Value> args[kArgc] = { a };
foo->Call(env->Global(), kArgc, args);
- // Setup break point and step through the function.
+ // Set up break point and step through the function.
SetBreakPoint(foo, 3);
step_action = StepNext;
break_point_hit_count = 0;
@@ -2790,7 +2790,7 @@ TEST(DebugStepKeyedStoreLoop) {
v8::Handle<v8::Value> args[kArgc] = { a };
foo->Call(env->Global(), kArgc, args);
- // Setup break point and step through the function.
+ // Set up break point and step through the function.
SetBreakPoint(foo, 3);
step_action = StepNext;
break_point_hit_count = 0;
@@ -2834,7 +2834,7 @@ TEST(DebugStepNamedLoadLoop) {
// Call function without any break points to ensure inlining is in place.
foo->Call(env->Global(), 0, NULL);
- // Setup break point and step through the function.
+ // Set up break point and step through the function.
SetBreakPoint(foo, 4);
step_action = StepNext;
break_point_hit_count = 0;
@@ -2869,7 +2869,7 @@ static void DoDebugStepNamedStoreLoop(int expected) {
// Call function without any break points to ensure inlining is in place.
foo->Call(env->Global(), 0, NULL);
- // Setup break point and step through the function.
+ // Set up break point and step through the function.
SetBreakPoint(foo, 3);
step_action = StepNext;
break_point_hit_count = 0;
@@ -5709,7 +5709,7 @@ void HostDispatchV8Thread::Run() {
v8::HandleScope scope;
DebugLocalContext env;
- // Setup message and host dispatch handlers.
+ // Set up message and host dispatch handlers.
v8::Debug::SetMessageHandler2(HostDispatchMessageHandler);
v8::Debug::SetHostDispatchHandler(HostDispatchDispatchHandler, 10 /* ms */);
@@ -5797,7 +5797,7 @@ void DebugMessageDispatchV8Thread::Run() {
v8::HandleScope scope;
DebugLocalContext env;
- // Setup debug message dispatch handler.
+ // Set up debug message dispatch handler.
v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler);
CompileRun("var y = 1 + 2;\n");
@@ -5851,7 +5851,7 @@ TEST(DebuggerAgent) {
bool ok;
// Initialize the socket library.
- i::Socket::Setup();
+ i::Socket::SetUp();
// Test starting and stopping the agent without any client connection.
debugger->StartAgent("test", kPort1);
@@ -5949,7 +5949,7 @@ TEST(DebuggerAgentProtocolOverflowHeader) {
OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort);
// Initialize the socket library.
- i::Socket::Setup();
+ i::Socket::SetUp();
// Create a socket server to receive a debugger agent message.
DebuggerAgentProtocolServerThread* server =
diff --git a/deps/v8/test/cctest/test-disasm-arm.cc b/deps/v8/test/cctest/test-disasm-arm.cc
index 032e6bc0fc..0e9432d95d 100644
--- a/deps/v8/test/cctest/test-disasm-arm.cc
+++ b/deps/v8/test/cctest/test-disasm-arm.cc
@@ -69,10 +69,10 @@ bool DisassembleAndCompare(byte* pc, const char* compare_string) {
}
-// Setup V8 to a state where we can at least run the assembler and
+// Set up V8 to a state where we can at least run the assembler and
// disassembler. Declare the variables and allocate the data structures used
// in the rest of the macros.
-#define SETUP() \
+#define SET_UP() \
InitializeVM(); \
v8::HandleScope scope; \
byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
@@ -102,7 +102,7 @@ if (failure) { \
TEST(Type0) {
- SETUP();
+ SET_UP();
COMPARE(and_(r0, r1, Operand(r2)),
"e0010002 and r0, r1, r2");
@@ -329,7 +329,7 @@ TEST(Type0) {
TEST(Type1) {
- SETUP();
+ SET_UP();
COMPARE(and_(r0, r1, Operand(0x00000000)),
"e2010000 and r0, r1, #0");
@@ -358,7 +358,7 @@ TEST(Type1) {
TEST(Type3) {
- SETUP();
+ SET_UP();
if (CpuFeatures::IsSupported(ARMv7)) {
COMPARE(ubfx(r0, r1, 5, 10),
@@ -413,7 +413,7 @@ TEST(Type3) {
TEST(Vfp) {
- SETUP();
+ SET_UP();
if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
@@ -546,7 +546,7 @@ TEST(Vfp) {
TEST(LoadStore) {
- SETUP();
+ SET_UP();
COMPARE(ldrb(r0, MemOperand(r1)),
"e5d10000 ldrb r0, [r1, #+0]");
diff --git a/deps/v8/test/cctest/test-disasm-mips.cc b/deps/v8/test/cctest/test-disasm-mips.cc
index 5ad99d7a39..8eadc6483b 100644
--- a/deps/v8/test/cctest/test-disasm-mips.cc
+++ b/deps/v8/test/cctest/test-disasm-mips.cc
@@ -71,10 +71,10 @@ bool DisassembleAndCompare(byte* pc, const char* compare_string) {
}
-// Setup V8 to a state where we can at least run the assembler and
+// Set up V8 to a state where we can at least run the assembler and
// disassembler. Declare the variables and allocate the data structures used
// in the rest of the macros.
-#define SETUP() \
+#define SET_UP() \
InitializeVM(); \
v8::HandleScope scope; \
byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
@@ -104,7 +104,7 @@ if (failure) { \
TEST(Type0) {
- SETUP();
+ SET_UP();
COMPARE(addu(a0, a1, a2),
"00a62021 addu a0, a1, a2");
diff --git a/deps/v8/test/cctest/test-hashing.cc b/deps/v8/test/cctest/test-hashing.cc
index df1ab20013..a6265105eb 100644
--- a/deps/v8/test/cctest/test-hashing.cc
+++ b/deps/v8/test/cctest/test-hashing.cc
@@ -46,65 +46,106 @@ typedef uint32_t (*HASH_FUNCTION)();
static v8::Persistent<v8::Context> env;
-#define __ assm->
+#define __ masm->
-void generate(MacroAssembler* assm, i::Vector<const char> string) {
+void generate(MacroAssembler* masm, i::Vector<const char> string) {
+ // GenerateHashInit takes the first character as an argument so it can't
+ // handle the zero length string.
+ ASSERT(string.length() > 0);
#ifdef V8_TARGET_ARCH_IA32
__ push(ebx);
__ push(ecx);
__ mov(eax, Immediate(0));
- if (string.length() > 0) {
- __ mov(ebx, Immediate(string.at(0)));
- StringHelper::GenerateHashInit(assm, eax, ebx, ecx);
- }
+ __ mov(ebx, Immediate(string.at(0)));
+ StringHelper::GenerateHashInit(masm, eax, ebx, ecx);
for (int i = 1; i < string.length(); i++) {
__ mov(ebx, Immediate(string.at(i)));
- StringHelper::GenerateHashAddCharacter(assm, eax, ebx, ecx);
+ StringHelper::GenerateHashAddCharacter(masm, eax, ebx, ecx);
}
- StringHelper::GenerateHashGetHash(assm, eax, ecx);
+ StringHelper::GenerateHashGetHash(masm, eax, ecx);
__ pop(ecx);
__ pop(ebx);
__ Ret();
#elif V8_TARGET_ARCH_X64
+ __ push(kRootRegister);
+ __ InitializeRootRegister();
__ push(rbx);
__ push(rcx);
__ movq(rax, Immediate(0));
- if (string.length() > 0) {
- __ movq(rbx, Immediate(string.at(0)));
- StringHelper::GenerateHashInit(assm, rax, rbx, rcx);
- }
+ __ movq(rbx, Immediate(string.at(0)));
+ StringHelper::GenerateHashInit(masm, rax, rbx, rcx);
for (int i = 1; i < string.length(); i++) {
__ movq(rbx, Immediate(string.at(i)));
- StringHelper::GenerateHashAddCharacter(assm, rax, rbx, rcx);
+ StringHelper::GenerateHashAddCharacter(masm, rax, rbx, rcx);
}
- StringHelper::GenerateHashGetHash(assm, rax, rcx);
+ StringHelper::GenerateHashGetHash(masm, rax, rcx);
__ pop(rcx);
__ pop(rbx);
+ __ pop(kRootRegister);
__ Ret();
#elif V8_TARGET_ARCH_ARM
+ __ push(kRootRegister);
+ __ InitializeRootRegister();
+
__ mov(r0, Operand(0));
- if (string.length() > 0) {
- __ mov(ip, Operand(string.at(0)));
- StringHelper::GenerateHashInit(assm, r0, ip);
- }
+ __ mov(ip, Operand(string.at(0)));
+ StringHelper::GenerateHashInit(masm, r0, ip);
for (int i = 1; i < string.length(); i++) {
__ mov(ip, Operand(string.at(i)));
- StringHelper::GenerateHashAddCharacter(assm, r0, ip);
+ StringHelper::GenerateHashAddCharacter(masm, r0, ip);
}
- StringHelper::GenerateHashGetHash(assm, r0);
+ StringHelper::GenerateHashGetHash(masm, r0);
+ __ pop(kRootRegister);
__ mov(pc, Operand(lr));
#elif V8_TARGET_ARCH_MIPS
+ __ push(kRootRegister);
+ __ InitializeRootRegister();
+
__ li(v0, Operand(0));
- if (string.length() > 0) {
- __ li(t1, Operand(string.at(0)));
- StringHelper::GenerateHashInit(assm, v0, t1);
- }
+ __ li(t1, Operand(string.at(0)));
+ StringHelper::GenerateHashInit(masm, v0, t1);
for (int i = 1; i < string.length(); i++) {
__ li(t1, Operand(string.at(i)));
- StringHelper::GenerateHashAddCharacter(assm, v0, t1);
+ StringHelper::GenerateHashAddCharacter(masm, v0, t1);
}
- StringHelper::GenerateHashGetHash(assm, v0);
+ StringHelper::GenerateHashGetHash(masm, v0);
+ __ pop(kRootRegister);
+ __ jr(ra);
+ __ nop();
+#endif
+}
+
+
+void generate(MacroAssembler* masm, uint32_t key) {
+#ifdef V8_TARGET_ARCH_IA32
+ __ push(ebx);
+ __ mov(eax, Immediate(key));
+ __ GetNumberHash(eax, ebx);
+ __ pop(ebx);
+ __ Ret();
+#elif V8_TARGET_ARCH_X64
+ __ push(kRootRegister);
+ __ InitializeRootRegister();
+ __ push(rbx);
+ __ movq(rax, Immediate(key));
+ __ GetNumberHash(rax, rbx);
+ __ pop(rbx);
+ __ pop(kRootRegister);
+ __ Ret();
+#elif V8_TARGET_ARCH_ARM
+ __ push(kRootRegister);
+ __ InitializeRootRegister();
+ __ mov(r0, Operand(key));
+ __ GetNumberHash(r0, ip);
+ __ pop(kRootRegister);
+ __ mov(pc, Operand(lr));
+#elif V8_TARGET_ARCH_MIPS
+ __ push(kRootRegister);
+ __ InitializeRootRegister();
+ __ li(v0, Operand(key));
+ __ GetNumberHash(v0, t1);
+ __ pop(kRootRegister);
__ jr(ra);
__ nop();
#endif
@@ -114,12 +155,12 @@ void generate(MacroAssembler* assm, i::Vector<const char> string) {
void check(i::Vector<const char> string) {
v8::HandleScope scope;
v8::internal::byte buffer[2048];
- MacroAssembler assm(Isolate::Current(), buffer, sizeof buffer);
+ MacroAssembler masm(Isolate::Current(), buffer, sizeof buffer);
- generate(&assm, string);
+ generate(&masm, string);
CodeDesc desc;
- assm.GetCode(&desc);
+ masm.GetCode(&desc);
Code* code = Code::cast(HEAP->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
@@ -140,12 +181,47 @@ void check(i::Vector<const char> string) {
}
+void check(uint32_t key) {
+ v8::HandleScope scope;
+ v8::internal::byte buffer[2048];
+ MacroAssembler masm(Isolate::Current(), buffer, sizeof buffer);
+
+ generate(&masm, key);
+
+ CodeDesc desc;
+ masm.GetCode(&desc);
+ Code* code = Code::cast(HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked());
+ CHECK(code->IsCode());
+
+ HASH_FUNCTION hash = FUNCTION_CAST<HASH_FUNCTION>(code->entry());
+#ifdef USE_SIMULATOR
+ uint32_t codegen_hash =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(hash, 0, 0, 0, 0, 0));
+#else
+ uint32_t codegen_hash = hash();
+#endif
+
+ uint32_t runtime_hash = ComputeIntegerHash(
+ key,
+ Isolate::Current()->heap()->HashSeed());
+ CHECK(runtime_hash == codegen_hash);
+}
+
+
void check_twochars(char a, char b) {
char ab[2] = {a, b};
check(i::Vector<const char>(ab, 2));
}
+static uint32_t PseudoRandom(uint32_t i, uint32_t j) {
+ return ~(~((i * 781) ^ (j * 329)));
+}
+
+
TEST(StringHash) {
if (env.IsEmpty()) env = v8::Context::New();
for (int a = 0; a < String::kMaxAsciiCharCode; a++) {
@@ -156,7 +232,6 @@ TEST(StringHash) {
check_twochars(static_cast<char>(a), static_cast<char>(b));
}
}
- check(i::Vector<const char>("", 0));
check(i::Vector<const char>("*", 1));
check(i::Vector<const char>(".zZ", 3));
check(i::Vector<const char>("muc", 3));
@@ -164,4 +239,22 @@ TEST(StringHash) {
check(i::Vector<const char>("-=[ vee eight ftw ]=-", 21));
}
+
+TEST(NumberHash) {
+ if (env.IsEmpty()) env = v8::Context::New();
+
+ // Some specific numbers
+ for (uint32_t key = 0; key < 42; key += 7) {
+ check(key);
+ }
+
+ // Some pseudo-random numbers
+ static const uint32_t kLimit = 1000;
+ for (uint32_t i = 0; i < 5; i++) {
+ for (uint32_t j = 0; j < 5; j++) {
+ check(PseudoRandom(i, j) % kLimit);
+ }
+ }
+}
+
#undef __
diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc
index 42b5789d4d..1e4e332b4e 100644
--- a/deps/v8/test/cctest/test-heap.cc
+++ b/deps/v8/test/cctest/test-heap.cc
@@ -1187,6 +1187,44 @@ TEST(TestInternalWeakListsTraverseWithGC) {
}
+TEST(TestSizeOfObjects) {
+ v8::V8::Initialize();
+
+ // Get initial heap size after several full GCs, which will stabilize
+ // the heap size and return with sweeping finished completely.
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ CHECK(HEAP->old_pointer_space()->IsSweepingComplete());
+ int initial_size = static_cast<int>(HEAP->SizeOfObjects());
+
+ {
+ // Allocate objects on several different old-space pages so that
+ // lazy sweeping kicks in for subsequent GC runs.
+ AlwaysAllocateScope always_allocate;
+ int filler_size = static_cast<int>(FixedArray::SizeFor(8192));
+ for (int i = 1; i <= 100; i++) {
+ HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked();
+ CHECK_EQ(initial_size + i * filler_size,
+ static_cast<int>(HEAP->SizeOfObjects()));
+ }
+ }
+
+ // The heap size should go back to initial size after a full GC, even
+ // though sweeping didn't finish yet.
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ CHECK(!HEAP->old_pointer_space()->IsSweepingComplete());
+ CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
+
+ // Advancing the sweeper step-wise should not change the heap size.
+ while (!HEAP->old_pointer_space()->IsSweepingComplete()) {
+ HEAP->old_pointer_space()->AdvanceSweeper(KB);
+ CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
+ }
+}
+
+
TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
InitializeVM();
HEAP->EnsureHeapIsIterable();
@@ -1476,3 +1514,61 @@ TEST(LeakGlobalContextViaMapProto) {
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
+
+
+TEST(InstanceOfStubWriteBarrier) {
+ i::FLAG_allow_natives_syntax = true;
+#ifdef DEBUG
+ i::FLAG_verify_heap = true;
+#endif
+ InitializeVM();
+ if (!i::V8::UseCrankshaft()) return;
+ v8::HandleScope outer_scope;
+
+ {
+ v8::HandleScope scope;
+ CompileRun(
+ "function foo () { }"
+ "function mkbar () { return new (new Function(\"\")) (); }"
+ "function f (x) { return (x instanceof foo); }"
+ "function g () { f(mkbar()); }"
+ "f(new foo()); f(new foo());"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f(new foo()); g();");
+ }
+
+ IncrementalMarking* marking = HEAP->incremental_marking();
+ marking->Abort();
+ marking->Start();
+
+ Handle<JSFunction> f =
+ v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(
+ v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+
+ CHECK(f->IsOptimized());
+
+ while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) &&
+ !marking->IsStopped()) {
+ marking->Step(MB);
+ }
+
+ CHECK(marking->IsMarking());
+
+ // Discard any pending GC requests otherwise we will get GC when we enter
+ // code below.
+ if (ISOLATE->stack_guard()->IsGCRequest()) {
+ ISOLATE->stack_guard()->Continue(GC_REQUEST);
+ }
+
+ {
+ v8::HandleScope scope;
+ v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global();
+ v8::Handle<v8::Function> g =
+ v8::Handle<v8::Function>::Cast(global->Get(v8_str("g")));
+ g->Call(global, 0, NULL);
+ }
+
+ HEAP->incremental_marking()->set_should_hurry(true);
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
+}
diff --git a/deps/v8/test/cctest/test-platform-linux.cc b/deps/v8/test/cctest/test-platform-linux.cc
index 756b9473c9..2a8d497850 100644
--- a/deps/v8/test/cctest/test-platform-linux.cc
+++ b/deps/v8/test/cctest/test-platform-linux.cc
@@ -67,7 +67,7 @@ TEST(BusyLock) {
TEST(VirtualMemory) {
- OS::Setup();
+ OS::SetUp();
VirtualMemory* vm = new VirtualMemory(1 * MB);
CHECK(vm->IsReserved());
void* block_addr = vm->address();
diff --git a/deps/v8/test/cctest/test-platform-win32.cc b/deps/v8/test/cctest/test-platform-win32.cc
index 9bd0014c6f..36b30aaceb 100644
--- a/deps/v8/test/cctest/test-platform-win32.cc
+++ b/deps/v8/test/cctest/test-platform-win32.cc
@@ -13,7 +13,7 @@ using namespace ::v8::internal;
TEST(VirtualMemory) {
- OS::Setup();
+ OS::SetUp();
VirtualMemory* vm = new VirtualMemory(1 * MB);
CHECK(vm->IsReserved());
void* block_addr = vm->address();
diff --git a/deps/v8/test/cctest/test-sockets.cc b/deps/v8/test/cctest/test-sockets.cc
index 4af55dbe9b..ad7354002f 100644
--- a/deps/v8/test/cctest/test-sockets.cc
+++ b/deps/v8/test/cctest/test-sockets.cc
@@ -129,7 +129,7 @@ TEST(Socket) {
bool ok;
// Initialize socket support.
- ok = Socket::Setup();
+ ok = Socket::SetUp();
CHECK(ok);
// Send and receive some data.
diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc
index ee60086ed2..6e495bc169 100644
--- a/deps/v8/test/cctest/test-spaces.cc
+++ b/deps/v8/test/cctest/test-spaces.cc
@@ -125,14 +125,14 @@ class TestMemoryAllocatorScope {
TEST(MemoryAllocator) {
- OS::Setup();
+ OS::SetUp();
Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
Heap* heap = isolate->heap();
CHECK(isolate->heap()->ConfigureHeapDefault());
MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
- CHECK(memory_allocator->Setup(heap->MaxReserved(),
+ CHECK(memory_allocator->SetUp(heap->MaxReserved(),
heap->MaxExecutableSize()));
int total_pages = 0;
@@ -175,21 +175,21 @@ TEST(MemoryAllocator) {
TEST(NewSpace) {
- OS::Setup();
+ OS::SetUp();
Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
Heap* heap = isolate->heap();
CHECK(heap->ConfigureHeapDefault());
MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
- CHECK(memory_allocator->Setup(heap->MaxReserved(),
+ CHECK(memory_allocator->SetUp(heap->MaxReserved(),
heap->MaxExecutableSize()));
TestMemoryAllocatorScope test_scope(isolate, memory_allocator);
NewSpace new_space(heap);
- CHECK(new_space.Setup(HEAP->ReservedSemiSpaceSize(),
+ CHECK(new_space.SetUp(HEAP->ReservedSemiSpaceSize(),
HEAP->ReservedSemiSpaceSize()));
- CHECK(new_space.HasBeenSetup());
+ CHECK(new_space.HasBeenSetUp());
while (new_space.Available() >= Page::kMaxHeapObjectSize) {
Object* obj =
@@ -204,13 +204,13 @@ TEST(NewSpace) {
TEST(OldSpace) {
- OS::Setup();
+ OS::SetUp();
Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
Heap* heap = isolate->heap();
CHECK(heap->ConfigureHeapDefault());
MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
- CHECK(memory_allocator->Setup(heap->MaxReserved(),
+ CHECK(memory_allocator->SetUp(heap->MaxReserved(),
heap->MaxExecutableSize()));
TestMemoryAllocatorScope test_scope(isolate, memory_allocator);
@@ -220,7 +220,7 @@ TEST(OldSpace) {
NOT_EXECUTABLE);
CHECK(s != NULL);
- CHECK(s->Setup());
+ CHECK(s->SetUp());
while (s->Available() > 0) {
s->AllocateRaw(Page::kMaxHeapObjectSize)->ToObjectUnchecked();
diff --git a/deps/v8/test/cctest/test-utils.cc b/deps/v8/test/cctest/test-utils.cc
index e4f70df409..df8ff72e4f 100644
--- a/deps/v8/test/cctest/test-utils.cc
+++ b/deps/v8/test/cctest/test-utils.cc
@@ -105,7 +105,7 @@ void TestMemCopy(Vector<byte> src,
TEST(MemCopy) {
v8::V8::Initialize();
- OS::Setup();
+ OS::SetUp();
const int N = OS::kMinComplexMemCopy + 128;
Vector<byte> buffer1 = Vector<byte>::New(N);
Vector<byte> buffer2 = Vector<byte>::New(N);
diff --git a/deps/v8/test/mjsunit/external-array.js b/deps/v8/test/mjsunit/external-array.js
index 81c6cfe8b4..72cfd85956 100644
--- a/deps/v8/test/mjsunit/external-array.js
+++ b/deps/v8/test/mjsunit/external-array.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -43,6 +43,50 @@ f(a);
assertEquals(0, a[0]);
assertEquals(0, a[1]);
+// No-parameter constructor should fail right now.
+function abfunc1() {
+ return new ArrayBuffer();
+}
+assertThrows(abfunc1);
+
+// Test derivation from an ArrayBuffer
+var ab = new ArrayBuffer(12);
+var derived_uint8 = new Uint8Array(ab);
+assertEquals(12, derived_uint8.length);
+var derived_uint32 = new Uint32Array(ab);
+assertEquals(3, derived_uint32.length);
+var derived_uint32_2 = new Uint32Array(ab,4);
+assertEquals(2, derived_uint32_2.length);
+var derived_uint32_3 = new Uint32Array(ab,4,1);
+assertEquals(1, derived_uint32_3.length);
+
+// If a given byteOffset and length references an area beyond the end of the
+// ArrayBuffer an exception is raised.
+function abfunc3() {
+ new Uint32Array(ab,4,3);
+}
+assertThrows(abfunc3);
+function abfunc4() {
+ new Uint32Array(ab,16);
+}
+assertThrows(abfunc4);
+
+// The given byteOffset must be a multiple of the element size of the specific
+// type, otherwise an exception is raised.
+function abfunc5() {
+ new Uint32Array(ab,5);
+}
+assertThrows(abfunc5);
+
+// If length is not explicitly specified, the length of the ArrayBuffer minus
+// the byteOffset must be a multiple of the element size of the specific type,
+// or an exception is raised.
+var ab2 = new ArrayBuffer(13);
+function abfunc6() {
+ new Uint32Array(ab2,4);
+}
+assertThrows(abfunc6);
+
// Test the correct behavior of the |BYTES_PER_ELEMENT| property (which is
// "constant", but not read-only).
a = new Int32Array(2);
diff --git a/deps/v8/test/mjsunit/math-min-max.js b/deps/v8/test/mjsunit/math-min-max.js
index 0833c5c809..7717b3bff2 100644
--- a/deps/v8/test/mjsunit/math-min-max.js
+++ b/deps/v8/test/mjsunit/math-min-max.js
@@ -115,3 +115,67 @@ assertEquals(NaN, Math.max(1, 'oxen'));
assertEquals(Infinity, 1/Math.max(ZERO, -0));
assertEquals(Infinity, 1/Math.max(-0, ZERO));
+
+function run(crankshaft_test) {
+ crankshaft_test(1);
+ crankshaft_test(1);
+ %OptimizeFunctionOnNextCall(crankshaft_test);
+ crankshaft_test(-0);
+}
+
+function crankshaft_test_1(arg) {
+ var v1 = 1;
+ var v2 = 5;
+ var v3 = 1.5;
+ var v4 = 5.5;
+ var v5 = 2;
+ var v6 = 6;
+ var v7 = 0;
+ var v8 = -0;
+
+ var v9 = 9.9;
+ var v0 = 10.1;
+ // Integer32 representation.
+ assertEquals(v2, Math.max(v1++, v2++));
+ assertEquals(v1, Math.min(v1++, v2++));
+ // Tagged representation.
+ assertEquals(v4, Math.max(v3, v4));
+ assertEquals(v3, Math.min(v3, v4));
+ assertEquals(v6, Math.max(v5, v6));
+ assertEquals(v5, Math.min(v5, v6));
+ // Double representation.
+ assertEquals(v0, Math.max(v0++, v9++));
+ assertEquals(v9, Math.min(v0++, v9++));
+ // Minus zero.
+ assertEquals(Infinity, 1/Math.max(v7, v8));
+ assertEquals(-Infinity, 1/Math.min(v7, v8));
+ // NaN.
+ assertEquals(NaN, Math.max(NaN, v8));
+ assertEquals(NaN, Math.min(NaN, v9));
+ assertEquals(NaN, Math.max(v8, NaN));
+ assertEquals(NaN, Math.min(v9, NaN));
+ // Minus zero as Integer32.
+ assertEquals((arg === -0) ? -Infinity : 1, 1/Math.min(arg, v2));
+}
+
+run(crankshaft_test_1);
+
+function crankshaft_test_2() {
+ var v9 = {};
+ v9.valueOf = function() { return 6; }
+ // Deopt expected due to non-heapnumber objects.
+ assertEquals(6, Math.min(v9, 12));
+}
+
+run(crankshaft_test_2);
+
+// Test overriding Math.min and Math.max
+Math.min = function(a, b) { return a + b; }
+Math.max = function(a, b) { return a - b; }
+
+function crankshaft_test_3() {
+ assertEquals(8, Math.min(3, 5));
+ assertEquals(3, Math.max(5, 2));
+}
+
+run(crankshaft_test_3);
diff --git a/deps/v8/test/mjsunit/regress/regress-109195.js b/deps/v8/test/mjsunit/regress/regress-109195.js
new file mode 100644
index 0000000000..97538aa167
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-109195.js
@@ -0,0 +1,65 @@
+// Copyright 2012 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-debug-as debug
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ for (var i = 0, n = exec_state.frameCount(); i < n; i++) {
+ exec_state.frame().scopeCount(i);
+ }
+ exec_state.prepareStep(Debug.StepAction.Continue, 1);
+}
+
+Debug.setListener(listener);
+
+var F = function () {
+ 1, function () {
+ var d = 0;
+ (function () { d; });
+ debugger;
+ }();
+};
+
+var src = "(" + F.toString() + ")()";
+eval(src);
+
+Function.prototype.__defineGetter__("f", function () {
+ debugger;
+ return 0;
+});
+
+var G = function () {
+ 1, function () {
+ var d = 0;
+ (function () { d; });
+ debugger;
+ }['f'];
+};
+
+var src = "(" + G.toString() + ")()";
+eval(src);
diff --git a/deps/v8/test/mjsunit/regress/regress-1898.js b/deps/v8/test/mjsunit/regress/regress-1898.js
new file mode 100644
index 0000000000..5440446fbf
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-1898.js
@@ -0,0 +1,37 @@
+// Copyright 2012 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 f(x) {
+ Math.log(Math.min(0.1, Math.abs(x)));
+}
+
+f(0.1);
+f(0.1);
+%OptimizeFunctionOnNextCall(f);
+f(0.1);
diff --git a/deps/v8/tools/grokdump.py b/deps/v8/tools/grokdump.py
index 44f9518f63..9977289872 100755
--- a/deps/v8/tools/grokdump.py
+++ b/deps/v8/tools/grokdump.py
@@ -506,10 +506,10 @@ class MinidumpReader(object):
# List of V8 instance types. Obtained by adding the code below to any .cc file.
#
-# #define DUMP_TYPE(T) printf("%d: \"%s\",\n", T, #T);
+# #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", T, #T);
# struct P {
# P() {
-# printf("{\n");
+# printf("INSTANCE_TYPES = {\n");
# INSTANCE_TYPE_LIST(DUMP_TYPE)
# printf("}\n");
# }
@@ -556,34 +556,35 @@ INSTANCE_TYPES = {
144: "EXTERNAL_PIXEL_ARRAY_TYPE",
146: "FILLER_TYPE",
147: "ACCESSOR_INFO_TYPE",
- 148: "ACCESS_CHECK_INFO_TYPE",
- 149: "INTERCEPTOR_INFO_TYPE",
- 150: "CALL_HANDLER_INFO_TYPE",
- 151: "FUNCTION_TEMPLATE_INFO_TYPE",
- 152: "OBJECT_TEMPLATE_INFO_TYPE",
- 153: "SIGNATURE_INFO_TYPE",
- 154: "TYPE_SWITCH_INFO_TYPE",
- 155: "SCRIPT_TYPE",
- 156: "CODE_CACHE_TYPE",
- 157: "POLYMORPHIC_CODE_CACHE_TYPE",
- 160: "FIXED_ARRAY_TYPE",
+ 148: "ACCESSOR_PAIR_TYPE",
+ 149: "ACCESS_CHECK_INFO_TYPE",
+ 150: "INTERCEPTOR_INFO_TYPE",
+ 151: "CALL_HANDLER_INFO_TYPE",
+ 152: "FUNCTION_TEMPLATE_INFO_TYPE",
+ 153: "OBJECT_TEMPLATE_INFO_TYPE",
+ 154: "SIGNATURE_INFO_TYPE",
+ 155: "TYPE_SWITCH_INFO_TYPE",
+ 156: "SCRIPT_TYPE",
+ 157: "CODE_CACHE_TYPE",
+ 158: "POLYMORPHIC_CODE_CACHE_TYPE",
+ 161: "FIXED_ARRAY_TYPE",
145: "FIXED_DOUBLE_ARRAY_TYPE",
- 161: "SHARED_FUNCTION_INFO_TYPE",
- 162: "JS_MESSAGE_OBJECT_TYPE",
- 165: "JS_VALUE_TYPE",
- 166: "JS_OBJECT_TYPE",
- 167: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
- 168: "JS_GLOBAL_OBJECT_TYPE",
- 169: "JS_BUILTINS_OBJECT_TYPE",
- 170: "JS_GLOBAL_PROXY_TYPE",
- 171: "JS_ARRAY_TYPE",
- 164: "JS_PROXY_TYPE",
- 174: "JS_WEAK_MAP_TYPE",
- 175: "JS_REGEXP_TYPE",
- 176: "JS_FUNCTION_TYPE",
- 163: "JS_FUNCTION_PROXY_TYPE",
- 158: "DEBUG_INFO_TYPE",
- 159: "BREAK_POINT_INFO_TYPE",
+ 162: "SHARED_FUNCTION_INFO_TYPE",
+ 163: "JS_MESSAGE_OBJECT_TYPE",
+ 166: "JS_VALUE_TYPE",
+ 167: "JS_OBJECT_TYPE",
+ 168: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
+ 169: "JS_GLOBAL_OBJECT_TYPE",
+ 170: "JS_BUILTINS_OBJECT_TYPE",
+ 171: "JS_GLOBAL_PROXY_TYPE",
+ 172: "JS_ARRAY_TYPE",
+ 165: "JS_PROXY_TYPE",
+ 175: "JS_WEAK_MAP_TYPE",
+ 176: "JS_REGEXP_TYPE",
+ 177: "JS_FUNCTION_TYPE",
+ 164: "JS_FUNCTION_PROXY_TYPE",
+ 159: "DEBUG_INFO_TYPE",
+ 160: "BREAK_POINT_INFO_TYPE",
}
diff --git a/deps/v8/tools/ll_prof.py b/deps/v8/tools/ll_prof.py
index 5c07d9165f..51ba672aca 100755
--- a/deps/v8/tools/ll_prof.py
+++ b/deps/v8/tools/ll_prof.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2010 the V8 project authors. All rights reserved.
+# Copyright 2012 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:
@@ -673,7 +673,9 @@ OBJDUMP_SECTION_HEADER_RE = re.compile(
OBJDUMP_SYMBOL_LINE_RE = re.compile(
r"^([a-f0-9]+)\s(.{7})\s(\S+)\s+([a-f0-9]+)\s+(?:\.hidden\s+)?(.*)$")
OBJDUMP_DYNAMIC_SYMBOLS_START_RE = re.compile(
- r"^DYNAMIC SYMBOL TABLE")
+ r"^DYNAMIC SYMBOL TABLE")
+OBJDUMP_SKIP_RE = re.compile(
+ r"^.*ld\.so\.cache$")
KERNEL_ALLSYMS_FILE = "/proc/kallsyms"
PERF_KERNEL_ALLSYMS_RE = re.compile(
r".*kallsyms.*")
@@ -692,6 +694,8 @@ class LibraryRepo(object):
# is 0.
if mmap_info.tid == 0 and not options.kernel:
return True
+ if OBJDUMP_SKIP_RE.match(mmap_info.filename):
+ return True
if PERF_KERNEL_ALLSYMS_RE.match(mmap_info.filename):
return self._LoadKernelSymbols(code_map)
self.infos.append(mmap_info)