summaryrefslogtreecommitdiff
path: root/deps/v8
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8')
-rw-r--r--deps/v8/src/arm/lithium-arm.cc10
-rw-r--r--deps/v8/src/arm/lithium-arm.h8
-rw-r--r--deps/v8/src/arm/lithium-codegen-arm.cc5
-rw-r--r--deps/v8/src/arm/stub-cache-arm.cc72
-rw-r--r--deps/v8/src/hydrogen.cc62
-rw-r--r--deps/v8/src/hydrogen.h13
-rw-r--r--deps/v8/src/ia32/lithium-codegen-ia32.cc5
-rw-r--r--deps/v8/src/ia32/lithium-ia32.cc10
-rw-r--r--deps/v8/src/ia32/lithium-ia32.h8
-rw-r--r--deps/v8/src/ia32/stub-cache-ia32.cc82
-rw-r--r--deps/v8/src/lithium.cc1
-rw-r--r--deps/v8/src/mips/lithium-codegen-mips.cc20
-rw-r--r--deps/v8/src/mips/lithium-mips.cc15
-rw-r--r--deps/v8/src/mips/lithium-mips.h22
-rw-r--r--deps/v8/src/mips/stub-cache-mips.cc75
-rw-r--r--deps/v8/src/objects.cc4
-rw-r--r--deps/v8/src/objects.h8
-rw-r--r--deps/v8/src/runtime.cc4
-rw-r--r--deps/v8/src/stub-cache.cc40
-rw-r--r--deps/v8/src/stub-cache.h34
-rw-r--r--deps/v8/src/version.cc2
-rw-r--r--deps/v8/src/x64/lithium-codegen-x64.cc5
-rw-r--r--deps/v8/src/x64/lithium-x64.cc10
-rw-r--r--deps/v8/src/x64/lithium-x64.h8
-rw-r--r--deps/v8/src/x64/stub-cache-x64.cc91
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2980.js64
-rw-r--r--deps/v8/test/mjsunit/regress/regress-298269.js45
-rw-r--r--deps/v8/test/mjsunit/regress/regress-319120.js28
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-318671.js38
29 files changed, 522 insertions, 267 deletions
diff --git a/deps/v8/src/arm/lithium-arm.cc b/deps/v8/src/arm/lithium-arm.cc
index 86d5d2b329..615c835bea 100644
--- a/deps/v8/src/arm/lithium-arm.cc
+++ b/deps/v8/src/arm/lithium-arm.cc
@@ -863,10 +863,12 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
LInstruction* instr = NULL;
if (current->CanReplaceWithDummyUses()) {
- HValue* first_operand = current->OperandCount() == 0
- ? graph()->GetConstant1()
- : current->OperandAt(0);
- instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand)));
+ if (current->OperandCount() == 0) {
+ instr = DefineAsRegister(new(zone()) LDummy());
+ } else {
+ instr = DefineAsRegister(new(zone())
+ LDummyUse(UseAny(current->OperandAt(0))));
+ }
for (int i = 1; i < current->OperandCount(); ++i) {
LInstruction* dummy =
new(zone()) LDummyUse(UseAny(current->OperandAt(i)));
diff --git a/deps/v8/src/arm/lithium-arm.h b/deps/v8/src/arm/lithium-arm.h
index ed07229e17..5087fb33d2 100644
--- a/deps/v8/src/arm/lithium-arm.h
+++ b/deps/v8/src/arm/lithium-arm.h
@@ -91,6 +91,7 @@ class LCodeGen;
V(DoubleToI) \
V(DoubleToSmi) \
V(Drop) \
+ V(Dummy) \
V(DummyUse) \
V(ElementsKind) \
V(ForInCacheArray) \
@@ -423,6 +424,13 @@ class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> {
};
+class LDummy V8_FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+ explicit LDummy() { }
+ DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
+};
+
+
class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
explicit LDummyUse(LOperand* value) {
diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc
index fbe8e171fa..8b22e625ba 100644
--- a/deps/v8/src/arm/lithium-codegen-arm.cc
+++ b/deps/v8/src/arm/lithium-codegen-arm.cc
@@ -5650,6 +5650,11 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
}
+void LCodeGen::DoDummy(LDummy* instr) {
+ // Nothing to see here, move on!
+}
+
+
void LCodeGen::DoDummyUse(LDummyUse* instr) {
// Nothing to see here, move on!
}
diff --git a/deps/v8/src/arm/stub-cache-arm.cc b/deps/v8/src/arm/stub-cache-arm.cc
index 004e067c82..923011fe08 100644
--- a/deps/v8/src/arm/stub-cache-arm.cc
+++ b/deps/v8/src/arm/stub-cache-arm.cc
@@ -121,18 +121,14 @@ static void ProbeTable(Isolate* isolate,
}
-// Helper function used to check that the dictionary doesn't contain
-// the property. This function may return false negatives, so miss_label
-// must always call a backup property check that is complete.
-// This function is safe to call if the receiver has fast properties.
-// Name must be unique and receiver must be a heap object.
-static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
- Label* miss_label,
- Register receiver,
- Handle<Name> name,
- Register scratch0,
- Register scratch1) {
+void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm,
+ Label* miss_label,
+ Register receiver,
+ Handle<Name> name,
+ Register scratch0,
+ Register scratch1) {
ASSERT(name->IsUniqueName());
+ ASSERT(!receiver.is(scratch0));
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
__ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
@@ -418,12 +414,12 @@ void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
// Generate code to check that a global property cell is empty. Create
// the property cell at compilation time if no cell exists for the
// property.
-static void GenerateCheckPropertyCell(MacroAssembler* masm,
- Handle<GlobalObject> global,
- Handle<Name> name,
- Register scratch,
- Label* miss) {
- Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name);
+void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm,
+ Handle<JSGlobalObject> global,
+ Handle<Name> name,
+ Register scratch,
+ Label* miss) {
+ Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
ASSERT(cell->value()->IsTheHole());
__ mov(scratch, Operand(cell));
__ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
@@ -441,7 +437,7 @@ void StoreStubCompiler::GenerateNegativeHolderLookup(
Label* miss) {
if (holder->IsJSGlobalObject()) {
GenerateCheckPropertyCell(
- masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss);
+ masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss);
} else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
GenerateDictionaryNegativeLookup(
masm, miss, holder_reg, name, scratch1(), scratch2());
@@ -1156,19 +1152,17 @@ class CallInterceptorCompiler BASE_EMBEDDED {
};
-// Calls GenerateCheckPropertyCell for each global object in the prototype chain
-// from object to (but not including) holder.
-static void GenerateCheckPropertyCells(MacroAssembler* masm,
- Handle<JSObject> object,
- Handle<JSObject> holder,
- Handle<Name> name,
- Register scratch,
- Label* miss) {
+void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm,
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<Name> name,
+ Register scratch,
+ Label* miss) {
Handle<JSObject> current = object;
while (!current.is_identical_to(holder)) {
- if (current->IsGlobalObject()) {
+ if (current->IsJSGlobalObject()) {
GenerateCheckPropertyCell(masm,
- Handle<GlobalObject>::cast(current),
+ Handle<JSGlobalObject>::cast(current),
name,
scratch,
miss);
@@ -1373,26 +1367,6 @@ Register LoadStubCompiler::CallbackHandlerFrontend(
}
-void LoadStubCompiler::NonexistentHandlerFrontend(
- Handle<JSObject> object,
- Handle<JSObject> last,
- Handle<Name> name,
- Label* success,
- Handle<GlobalObject> global) {
- Label miss;
-
- HandlerFrontendHeader(object, receiver(), last, name, &miss);
-
- // If the last object in the prototype chain is a global object,
- // check that the global property cell is empty.
- if (!global.is_null()) {
- GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
- }
-
- HandlerFrontendFooter(name, success, &miss);
-}
-
-
void LoadStubCompiler::GenerateLoadField(Register reg,
Handle<JSObject> holder,
PropertyIndex field,
@@ -2939,7 +2913,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
Handle<JSObject> object,
Handle<JSObject> last,
Handle<Name> name,
- Handle<GlobalObject> global) {
+ Handle<JSGlobalObject> global) {
Label success;
NonexistentHandlerFrontend(object, last, name, &success, global);
diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc
index 3b232e6e93..9587dd3440 100644
--- a/deps/v8/src/hydrogen.cc
+++ b/deps/v8/src/hydrogen.cc
@@ -708,6 +708,21 @@ DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false)
#undef DEFINE_GET_CONSTANT
+#define DEFINE_IS_CONSTANT(Name, name) \
+bool HGraph::IsConstant##Name(HConstant* constant) { \
+ return constant_##name##_.is_set() && constant == constant_##name##_.get(); \
+}
+DEFINE_IS_CONSTANT(Undefined, undefined)
+DEFINE_IS_CONSTANT(0, 0)
+DEFINE_IS_CONSTANT(1, 1)
+DEFINE_IS_CONSTANT(Minus1, minus1)
+DEFINE_IS_CONSTANT(True, true)
+DEFINE_IS_CONSTANT(False, false)
+DEFINE_IS_CONSTANT(Hole, the_hole)
+DEFINE_IS_CONSTANT(Null, null)
+
+#undef DEFINE_IS_CONSTANT
+
HConstant* HGraph::GetInvalidContext() {
return GetConstant(&constant_invalid_context_, 0xFFFFC0C7);
@@ -715,14 +730,14 @@ HConstant* HGraph::GetInvalidContext() {
bool HGraph::IsStandardConstant(HConstant* constant) {
- if (constant == GetConstantUndefined()) return true;
- if (constant == GetConstant0()) return true;
- if (constant == GetConstant1()) return true;
- if (constant == GetConstantMinus1()) return true;
- if (constant == GetConstantTrue()) return true;
- if (constant == GetConstantFalse()) return true;
- if (constant == GetConstantHole()) return true;
- if (constant == GetConstantNull()) return true;
+ if (IsConstantUndefined(constant)) return true;
+ if (IsConstant0(constant)) return true;
+ if (IsConstant1(constant)) return true;
+ if (IsConstantMinus1(constant)) return true;
+ if (IsConstantTrue(constant)) return true;
+ if (IsConstantFalse(constant)) return true;
+ if (IsConstantHole(constant)) return true;
+ if (IsConstantNull(constant)) return true;
return false;
}
@@ -2281,7 +2296,8 @@ HGraph::HGraph(CompilationInfo* info)
depends_on_empty_array_proto_elements_(false),
type_change_checksum_(0),
maximum_environment_size_(0),
- no_side_effects_scope_count_(0) {
+ no_side_effects_scope_count_(0),
+ disallow_adding_new_values_(false) {
if (info->IsStub()) {
HydrogenCodeStub* stub = info->code_stub();
CodeStubInterfaceDescriptor* descriptor =
@@ -7830,14 +7846,27 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(
// Special case for string addition here.
if (op == Token::ADD &&
(left_type->Is(Type::String()) || right_type->Is(Type::String()))) {
+ // Validate type feedback for left argument.
if (left_type->Is(Type::String())) {
IfBuilder if_isstring(this);
if_isstring.If<HIsStringAndBranch>(left);
if_isstring.Then();
if_isstring.ElseDeopt("Expected string for LHS of binary operation");
- } else if (left_type->Is(Type::Number())) {
+ }
+
+ // Validate type feedback for right argument.
+ if (right_type->Is(Type::String())) {
+ IfBuilder if_isstring(this);
+ if_isstring.If<HIsStringAndBranch>(right);
+ if_isstring.Then();
+ if_isstring.ElseDeopt("Expected string for RHS of binary operation");
+ }
+
+ // Convert left argument as necessary.
+ if (left_type->Is(Type::Number())) {
+ ASSERT(right_type->Is(Type::String()));
left = BuildNumberToString(left, left_type);
- } else {
+ } else if (!left_type->Is(Type::String())) {
ASSERT(right_type->Is(Type::String()));
HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT);
Add<HPushArgument>(left);
@@ -7845,14 +7874,11 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(
return NewUncasted<HInvokeFunction>(function, 2);
}
- if (right_type->Is(Type::String())) {
- IfBuilder if_isstring(this);
- if_isstring.If<HIsStringAndBranch>(right);
- if_isstring.Then();
- if_isstring.ElseDeopt("Expected string for RHS of binary operation");
- } else if (right_type->Is(Type::Number())) {
+ // Convert right argument as necessary.
+ if (right_type->Is(Type::Number())) {
+ ASSERT(left_type->Is(Type::String()));
right = BuildNumberToString(right, right_type);
- } else {
+ } else if (!right_type->Is(Type::String())) {
ASSERT(left_type->Is(Type::String()));
HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT);
Add<HPushArgument>(left);
diff --git a/deps/v8/src/hydrogen.h b/deps/v8/src/hydrogen.h
index b5046bd001..8f4878d93e 100644
--- a/deps/v8/src/hydrogen.h
+++ b/deps/v8/src/hydrogen.h
@@ -352,6 +352,14 @@ class HGraph V8_FINAL : public ZoneObject {
HConstant* GetConstantNull();
HConstant* GetInvalidContext();
+ bool IsConstantUndefined(HConstant* constant);
+ bool IsConstant0(HConstant* constant);
+ bool IsConstant1(HConstant* constant);
+ bool IsConstantMinus1(HConstant* constant);
+ bool IsConstantTrue(HConstant* constant);
+ bool IsConstantFalse(HConstant* constant);
+ bool IsConstantHole(HConstant* constant);
+ bool IsConstantNull(HConstant* constant);
bool IsStandardConstant(HConstant* constant);
HBasicBlock* CreateBasicBlock();
@@ -366,6 +374,7 @@ class HGraph V8_FINAL : public ZoneObject {
int GetMaximumValueID() const { return values_.length(); }
int GetNextBlockID() { return next_block_id_++; }
int GetNextValueID(HValue* value) {
+ ASSERT(!disallow_adding_new_values_);
values_.Add(value, zone());
return values_.length() - 1;
}
@@ -373,6 +382,9 @@ class HGraph V8_FINAL : public ZoneObject {
if (id >= 0 && id < values_.length()) return values_[id];
return NULL;
}
+ void DisallowAddingNewValues() {
+ disallow_adding_new_values_ = true;
+ }
bool Optimize(BailoutReason* bailout_reason);
@@ -499,6 +511,7 @@ class HGraph V8_FINAL : public ZoneObject {
int type_change_checksum_;
int maximum_environment_size_;
int no_side_effects_scope_count_;
+ bool disallow_adding_new_values_;
DISALLOW_COPY_AND_ASSIGN(HGraph);
};
diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.cc b/deps/v8/src/ia32/lithium-codegen-ia32.cc
index 46c87e1d62..0c7e8d6ef3 100644
--- a/deps/v8/src/ia32/lithium-codegen-ia32.cc
+++ b/deps/v8/src/ia32/lithium-codegen-ia32.cc
@@ -6216,6 +6216,11 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
}
+void LCodeGen::DoDummy(LDummy* instr) {
+ // Nothing to see here, move on!
+}
+
+
void LCodeGen::DoDummyUse(LDummyUse* instr) {
// Nothing to see here, move on!
}
diff --git a/deps/v8/src/ia32/lithium-ia32.cc b/deps/v8/src/ia32/lithium-ia32.cc
index fdddef3f47..73aabd6b1e 100644
--- a/deps/v8/src/ia32/lithium-ia32.cc
+++ b/deps/v8/src/ia32/lithium-ia32.cc
@@ -916,10 +916,12 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
LInstruction* instr = NULL;
if (current->CanReplaceWithDummyUses()) {
- HValue* first_operand = current->OperandCount() == 0
- ? graph()->GetConstant1()
- : current->OperandAt(0);
- instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand)));
+ if (current->OperandCount() == 0) {
+ instr = DefineAsRegister(new(zone()) LDummy());
+ } else {
+ instr = DefineAsRegister(new(zone())
+ LDummyUse(UseAny(current->OperandAt(0))));
+ }
for (int i = 1; i < current->OperandCount(); ++i) {
LInstruction* dummy =
new(zone()) LDummyUse(UseAny(current->OperandAt(i)));
diff --git a/deps/v8/src/ia32/lithium-ia32.h b/deps/v8/src/ia32/lithium-ia32.h
index 752fdd4f6a..9b00f3c358 100644
--- a/deps/v8/src/ia32/lithium-ia32.h
+++ b/deps/v8/src/ia32/lithium-ia32.h
@@ -93,6 +93,7 @@ class LCodeGen;
V(DoubleToI) \
V(DoubleToSmi) \
V(Drop) \
+ V(Dummy) \
V(DummyUse) \
V(ElementsKind) \
V(ForInCacheArray) \
@@ -431,6 +432,13 @@ class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> {
};
+class LDummy V8_FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+ explicit LDummy() { }
+ DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
+};
+
+
class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
explicit LDummyUse(LOperand* value) {
diff --git a/deps/v8/src/ia32/stub-cache-ia32.cc b/deps/v8/src/ia32/stub-cache-ia32.cc
index 9786cffe86..0648833dc7 100644
--- a/deps/v8/src/ia32/stub-cache-ia32.cc
+++ b/deps/v8/src/ia32/stub-cache-ia32.cc
@@ -137,38 +137,34 @@ static void ProbeTable(Isolate* isolate,
}
-// Helper function used to check that the dictionary doesn't contain
-// the property. This function may return false negatives, so miss_label
-// must always call a backup property check that is complete.
-// This function is safe to call if the receiver has fast properties.
-// Name must be unique and receiver must be a heap object.
-static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
- Label* miss_label,
- Register receiver,
- Handle<Name> name,
- Register r0,
- Register r1) {
+void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm,
+ Label* miss_label,
+ Register receiver,
+ Handle<Name> name,
+ Register scratch0,
+ Register scratch1) {
ASSERT(name->IsUniqueName());
+ ASSERT(!receiver.is(scratch0));
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->negative_lookups(), 1);
__ IncrementCounter(counters->negative_lookups_miss(), 1);
- __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset));
+ __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
const int kInterceptorOrAccessCheckNeededMask =
(1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
// Bail out if the receiver has a named interceptor or requires access checks.
- __ test_b(FieldOperand(r0, Map::kBitFieldOffset),
+ __ test_b(FieldOperand(scratch0, Map::kBitFieldOffset),
kInterceptorOrAccessCheckNeededMask);
__ j(not_zero, miss_label);
// Check that receiver is a JSObject.
- __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
+ __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE);
__ j(below, miss_label);
// Load properties array.
- Register properties = r0;
+ Register properties = scratch0;
__ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
// Check that the properties array is a dictionary.
@@ -182,7 +178,7 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
&done,
properties,
name,
- r1);
+ scratch1);
__ bind(&done);
__ DecrementCounter(counters->negative_lookups_miss(), 1);
}
@@ -792,13 +788,13 @@ void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
// Generate code to check that a global property cell is empty. Create
// the property cell at compilation time if no cell exists for the
// property.
-static void GenerateCheckPropertyCell(MacroAssembler* masm,
- Handle<GlobalObject> global,
- Handle<Name> name,
- Register scratch,
- Label* miss) {
+void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm,
+ Handle<JSGlobalObject> global,
+ Handle<Name> name,
+ Register scratch,
+ Label* miss) {
Handle<PropertyCell> cell =
- GlobalObject::EnsurePropertyCell(global, name);
+ JSGlobalObject::EnsurePropertyCell(global, name);
ASSERT(cell->value()->IsTheHole());
Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value();
if (Serializer::enabled()) {
@@ -820,7 +816,7 @@ void StoreStubCompiler::GenerateNegativeHolderLookup(
Label* miss) {
if (holder->IsJSGlobalObject()) {
GenerateCheckPropertyCell(
- masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss);
+ masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss);
} else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
GenerateDictionaryNegativeLookup(
masm, miss, holder_reg, name, scratch1(), scratch2());
@@ -1122,19 +1118,17 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
}
-// Calls GenerateCheckPropertyCell for each global object in the prototype chain
-// from object to (but not including) holder.
-static void GenerateCheckPropertyCells(MacroAssembler* masm,
- Handle<JSObject> object,
- Handle<JSObject> holder,
- Handle<Name> name,
- Register scratch,
- Label* miss) {
+void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm,
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<Name> name,
+ Register scratch,
+ Label* miss) {
Handle<JSObject> current = object;
while (!current.is_identical_to(holder)) {
- if (current->IsGlobalObject()) {
+ if (current->IsJSGlobalObject()) {
GenerateCheckPropertyCell(masm,
- Handle<GlobalObject>::cast(current),
+ Handle<JSGlobalObject>::cast(current),
name,
scratch,
miss);
@@ -1355,26 +1349,6 @@ Register LoadStubCompiler::CallbackHandlerFrontend(
}
-void LoadStubCompiler::NonexistentHandlerFrontend(
- Handle<JSObject> object,
- Handle<JSObject> last,
- Handle<Name> name,
- Label* success,
- Handle<GlobalObject> global) {
- Label miss;
-
- HandlerFrontendHeader(object, receiver(), last, name, &miss);
-
- // If the last object in the prototype chain is a global object,
- // check that the global property cell is empty.
- if (!global.is_null()) {
- GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
- }
-
- HandlerFrontendFooter(name, success, &miss);
-}
-
-
void LoadStubCompiler::GenerateLoadField(Register reg,
Handle<JSObject> holder,
PropertyIndex field,
@@ -3049,7 +3023,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
Handle<JSObject> object,
Handle<JSObject> last,
Handle<Name> name,
- Handle<GlobalObject> global) {
+ Handle<JSGlobalObject> global) {
Label success;
NonexistentHandlerFrontend(object, last, name, &success, global);
diff --git a/deps/v8/src/lithium.cc b/deps/v8/src/lithium.cc
index 1be4b0654b..966afa9c0b 100644
--- a/deps/v8/src/lithium.cc
+++ b/deps/v8/src/lithium.cc
@@ -422,6 +422,7 @@ Representation LChunk::LookupLiteralRepresentation(
LChunk* LChunk::NewChunk(HGraph* graph) {
DisallowHandleAllocation no_handles;
DisallowHeapAllocation no_gc;
+ graph->DisallowAddingNewValues();
int values = graph->GetMaximumValueID();
CompilationInfo* info = graph->info();
if (values > LUnallocated::kMaxVirtualRegisters) {
diff --git a/deps/v8/src/mips/lithium-codegen-mips.cc b/deps/v8/src/mips/lithium-codegen-mips.cc
index f54d4a5b0c..4484dc634e 100644
--- a/deps/v8/src/mips/lithium-codegen-mips.cc
+++ b/deps/v8/src/mips/lithium-codegen-mips.cc
@@ -4584,9 +4584,7 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
LOperand* input = instr->value();
- ASSERT(input->IsRegister());
LOperand* output = instr->result();
- ASSERT(output->IsRegister());
Register scratch = scratch0();
__ SmiTagCheckOverflow(ToRegister(output), ToRegister(input), scratch);
@@ -4607,6 +4605,19 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
}
+void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) {
+ LOperand* input = instr->value();
+ LOperand* output = instr->result();
+ if (!instr->hydrogen()->value()->HasRange() ||
+ !instr->hydrogen()->value()->range()->IsInSmiRange()) {
+ Register scratch = scratch0();
+ __ And(scratch, ToRegister(input), Operand(0xc0000000));
+ DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
+ }
+ __ SmiTag(ToRegister(output), ToRegister(input));
+}
+
+
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
class DeferredNumberTagI V8_FINAL : public LDeferredCode {
public:
@@ -5631,6 +5642,11 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
}
+void LCodeGen::DoDummy(LDummy* instr) {
+ // Nothing to see here, move on!
+}
+
+
void LCodeGen::DoDummyUse(LDummyUse* instr) {
// Nothing to see here, move on!
}
diff --git a/deps/v8/src/mips/lithium-mips.cc b/deps/v8/src/mips/lithium-mips.cc
index fb94bc3bdf..6b76ff7429 100644
--- a/deps/v8/src/mips/lithium-mips.cc
+++ b/deps/v8/src/mips/lithium-mips.cc
@@ -868,10 +868,12 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
LInstruction* instr = NULL;
if (current->CanReplaceWithDummyUses()) {
- HValue* first_operand = current->OperandCount() == 0
- ? graph()->GetConstant1()
- : current->OperandAt(0);
- instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand)));
+ if (current->OperandCount() == 0) {
+ instr = DefineAsRegister(new(zone()) LDummy());
+ } else {
+ instr = DefineAsRegister(new(zone())
+ LDummyUse(UseAny(current->OperandAt(0))));
+ }
for (int i = 1; i < current->OperandCount(); ++i) {
LInstruction* dummy =
new(zone()) LDummyUse(UseAny(current->OperandAt(i)));
@@ -1934,8 +1936,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
} else if (to.IsSmi()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val);
- LInstruction* result =
- DefineSameAsFirst(new(zone()) LInteger32ToSmi(value));
+ LInstruction* result = val->CheckFlag(HInstruction::kUint32)
+ ? DefineSameAsFirst(new(zone()) LUint32ToSmi(value))
+ : DefineSameAsFirst(new(zone()) LInteger32ToSmi(value));
if (val->HasRange() && val->range()->IsInSmiRange()) {
return result;
}
diff --git a/deps/v8/src/mips/lithium-mips.h b/deps/v8/src/mips/lithium-mips.h
index 301be8fdf2..518a3b8c65 100644
--- a/deps/v8/src/mips/lithium-mips.h
+++ b/deps/v8/src/mips/lithium-mips.h
@@ -91,6 +91,7 @@ class LCodeGen;
V(DoubleToI) \
V(DoubleToSmi) \
V(Drop) \
+ V(Dummy) \
V(DummyUse) \
V(ElementsKind) \
V(ForInCacheArray) \
@@ -182,6 +183,7 @@ class LCodeGen;
V(Typeof) \
V(TypeofIsAndBranch) \
V(Uint32ToDouble) \
+ V(Uint32ToSmi) \
V(UnknownOSRValue) \
V(ValueOf) \
V(WrapReceiver)
@@ -419,6 +421,13 @@ class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> {
};
+class LDummy V8_FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+ explicit LDummy() { }
+ DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
+};
+
+
class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
explicit LDummyUse(LOperand* value) {
@@ -2052,6 +2061,19 @@ class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
};
+class LUint32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LUint32ToSmi(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi")
+ DECLARE_HYDROGEN_ACCESSOR(Change)
+};
+
+
class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
explicit LNumberTagI(LOperand* value) {
diff --git a/deps/v8/src/mips/stub-cache-mips.cc b/deps/v8/src/mips/stub-cache-mips.cc
index 471c25ef82..17aa4aadef 100644
--- a/deps/v8/src/mips/stub-cache-mips.cc
+++ b/deps/v8/src/mips/stub-cache-mips.cc
@@ -117,18 +117,14 @@ static void ProbeTable(Isolate* isolate,
}
-// Helper function used to check that the dictionary doesn't contain
-// the property. This function may return false negatives, so miss_label
-// must always call a backup property check that is complete.
-// This function is safe to call if the receiver has fast properties.
-// Name must be unique and receiver must be a heap object.
-static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
- Label* miss_label,
- Register receiver,
- Handle<Name> name,
- Register scratch0,
- Register scratch1) {
+void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm,
+ Label* miss_label,
+ Register receiver,
+ Handle<Name> name,
+ Register scratch0,
+ Register scratch1) {
ASSERT(name->IsUniqueName());
+ ASSERT(!receiver.is(scratch0));
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
__ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
@@ -408,15 +404,12 @@ void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
}
-// Generate code to check that a global property cell is empty. Create
-// the property cell at compilation time if no cell exists for the
-// property.
-static void GenerateCheckPropertyCell(MacroAssembler* masm,
- Handle<GlobalObject> global,
- Handle<Name> name,
- Register scratch,
- Label* miss) {
- Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name);
+void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm,
+ Handle<JSGlobalObject> global,
+ Handle<Name> name,
+ Register scratch,
+ Label* miss) {
+ Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
ASSERT(cell->value()->IsTheHole());
__ li(scratch, Operand(cell));
__ lw(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
@@ -433,7 +426,7 @@ void StoreStubCompiler::GenerateNegativeHolderLookup(
Label* miss) {
if (holder->IsJSGlobalObject()) {
GenerateCheckPropertyCell(
- masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss);
+ masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss);
} else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
GenerateDictionaryNegativeLookup(
masm, miss, holder_reg, name, scratch1(), scratch2());
@@ -1149,19 +1142,17 @@ class CallInterceptorCompiler BASE_EMBEDDED {
};
-// Calls GenerateCheckPropertyCell for each global object in the prototype chain
-// from object to (but not including) holder.
-static void GenerateCheckPropertyCells(MacroAssembler* masm,
- Handle<JSObject> object,
- Handle<JSObject> holder,
- Handle<Name> name,
- Register scratch,
- Label* miss) {
+void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm,
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<Name> name,
+ Register scratch,
+ Label* miss) {
Handle<JSObject> current = object;
while (!current.is_identical_to(holder)) {
- if (current->IsGlobalObject()) {
+ if (current->IsJSGlobalObject()) {
GenerateCheckPropertyCell(masm,
- Handle<GlobalObject>::cast(current),
+ Handle<JSGlobalObject>::cast(current),
name,
scratch,
miss);
@@ -1364,26 +1355,6 @@ Register LoadStubCompiler::CallbackHandlerFrontend(
}
-void LoadStubCompiler::NonexistentHandlerFrontend(
- Handle<JSObject> object,
- Handle<JSObject> last,
- Handle<Name> name,
- Label* success,
- Handle<GlobalObject> global) {
- Label miss;
-
- HandlerFrontendHeader(object, receiver(), last, name, &miss);
-
- // If the last object in the prototype chain is a global object,
- // check that the global property cell is empty.
- if (!global.is_null()) {
- GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
- }
-
- HandlerFrontendFooter(name, success, &miss);
-}
-
-
void LoadStubCompiler::GenerateLoadField(Register reg,
Handle<JSObject> holder,
PropertyIndex field,
@@ -2957,7 +2928,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
Handle<JSObject> object,
Handle<JSObject> last,
Handle<Name> name,
- Handle<GlobalObject> global) {
+ Handle<JSGlobalObject> global) {
Label success;
NonexistentHandlerFrontend(object, last, name, &success, global);
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index f7c89175da..22c01bf1a3 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -14749,8 +14749,8 @@ PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) {
}
-Handle<PropertyCell> GlobalObject::EnsurePropertyCell(
- Handle<GlobalObject> global,
+Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell(
+ Handle<JSGlobalObject> global,
Handle<Name> name) {
ASSERT(!global->HasFastProperties());
int entry = global->property_dictionary()->FindEntry(*name);
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index e8c9850484..8331a76885 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -7389,10 +7389,6 @@ class GlobalObject: public JSObject {
return answer;
}
- // Ensure that the global object has a cell for the given property name.
- static Handle<PropertyCell> EnsurePropertyCell(Handle<GlobalObject> global,
- Handle<Name> name);
-
// Casting.
static inline GlobalObject* cast(Object* obj);
@@ -7414,6 +7410,10 @@ class JSGlobalObject: public GlobalObject {
// Casting.
static inline JSGlobalObject* cast(Object* obj);
+ // Ensure that the global object has a cell for the given property name.
+ static Handle<PropertyCell> EnsurePropertyCell(Handle<JSGlobalObject> global,
+ Handle<Name> name);
+
// Dispatched behavior.
DECLARE_PRINTER(JSGlobalObject)
DECLARE_VERIFIER(JSGlobalObject)
diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc
index 15cfc854bf..7f37af0bd7 100644
--- a/deps/v8/src/runtime.cc
+++ b/deps/v8/src/runtime.cc
@@ -961,12 +961,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
size_t length = NumberToSize(isolate, *length_obj);
- size_t byte_length = length * element_size;
- if (byte_length < length) { // Overflow
+ if (length > (kMaxInt / element_size)) {
return isolate->Throw(*isolate->factory()->
NewRangeError("invalid_array_buffer_length",
HandleVector<Object>(NULL, 0)));
}
+ size_t byte_length = length * element_size;
// NOTE: not initializing backing store.
// We assume that the caller of this function will initialize holder
diff --git a/deps/v8/src/stub-cache.cc b/deps/v8/src/stub-cache.cc
index 67002a36b1..1ec00d49bb 100644
--- a/deps/v8/src/stub-cache.cc
+++ b/deps/v8/src/stub-cache.cc
@@ -177,12 +177,12 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
Handle<Name> cache_name = factory()->empty_string();
Handle<JSObject> current;
Handle<Object> next = receiver;
- Handle<GlobalObject> global;
+ Handle<JSGlobalObject> global;
do {
current = Handle<JSObject>::cast(next);
next = Handle<Object>(current->GetPrototype(), isolate_);
- if (current->IsGlobalObject()) {
- global = Handle<GlobalObject>::cast(current);
+ if (current->IsJSGlobalObject()) {
+ global = Handle<JSGlobalObject>::cast(current);
cache_name = name;
} else if (!current->HasFastProperties()) {
cache_name = name;
@@ -1208,6 +1208,40 @@ Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<JSObject> object,
}
+void LoadStubCompiler::NonexistentHandlerFrontend(
+ Handle<JSObject> object,
+ Handle<JSObject> last,
+ Handle<Name> name,
+ Label* success,
+ Handle<JSGlobalObject> global) {
+ Label miss;
+
+ Register holder =
+ HandlerFrontendHeader(object, receiver(), last, name, &miss);
+
+ if (!last->HasFastProperties() &&
+ !last->IsJSGlobalObject() &&
+ !last->IsJSGlobalProxy()) {
+ if (!name->IsUniqueName()) {
+ ASSERT(name->IsString());
+ name = factory()->InternalizeString(Handle<String>::cast(name));
+ }
+ ASSERT(last->property_dictionary()->FindEntry(*name) ==
+ NameDictionary::kNotFound);
+ GenerateDictionaryNegativeLookup(masm(), &miss, holder, name,
+ scratch2(), scratch3());
+ }
+
+ // If the last object in the prototype chain is a global object,
+ // check that the global property cell is empty.
+ if (!global.is_null()) {
+ GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
+ }
+
+ HandlerFrontendFooter(name, success, &miss);
+}
+
+
Handle<Code> LoadStubCompiler::CompileLoadField(
Handle<JSObject> object,
Handle<JSObject> holder,
diff --git a/deps/v8/src/stub-cache.h b/deps/v8/src/stub-cache.h
index 38bc7a3c3a..42685b2059 100644
--- a/deps/v8/src/stub-cache.h
+++ b/deps/v8/src/stub-cache.h
@@ -434,6 +434,18 @@ class StubCompiler BASE_EMBEDDED {
int index,
Register prototype);
+ // Helper function used to check that the dictionary doesn't contain
+ // the property. This function may return false negatives, so miss_label
+ // must always call a backup property check that is complete.
+ // This function is safe to call if the receiver has fast properties.
+ // Name must be unique and receiver must be a heap object.
+ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
+ Label* miss_label,
+ Register receiver,
+ Handle<Name> name,
+ Register r0,
+ Register r1);
+
// Generates prototype loading code that uses the objects from the
// context we were in when this function was called. If the context
// has changed, a jump to miss is performed. This ties the generated
@@ -469,6 +481,24 @@ class StubCompiler BASE_EMBEDDED {
Register scratch2,
Label* miss_label);
+ // Generate code to check that a global property cell is empty. Create
+ // the property cell at compilation time if no cell exists for the
+ // property.
+ static void GenerateCheckPropertyCell(MacroAssembler* masm,
+ Handle<JSGlobalObject> global,
+ Handle<Name> name,
+ Register scratch,
+ Label* miss);
+
+ // Calls GenerateCheckPropertyCell for each global object in the prototype
+ // chain from object to (but not including) holder.
+ static void GenerateCheckPropertyCells(MacroAssembler* masm,
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<Name> name,
+ Register scratch,
+ Label* miss);
+
static void TailCallBuiltin(MacroAssembler* masm, Builtins::Name name);
// Generates code that verifies that the property holder has not changed
@@ -673,7 +703,7 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler {
Handle<Code> CompileLoadNonexistent(Handle<JSObject> object,
Handle<JSObject> last,
Handle<Name> name,
- Handle<GlobalObject> global);
+ Handle<JSGlobalObject> global);
Handle<Code> CompileLoadGlobal(Handle<JSObject> object,
Handle<GlobalObject> holder,
@@ -704,7 +734,7 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler {
Handle<JSObject> last,
Handle<Name> name,
Label* success,
- Handle<GlobalObject> global);
+ Handle<JSGlobalObject> global);
void GenerateLoadField(Register reg,
Handle<JSObject> holder,
diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc
index 6d4efa2261..dcf8df7e2a 100644
--- a/deps/v8/src/version.cc
+++ b/deps/v8/src/version.cc
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 22
#define BUILD_NUMBER 24
-#define PATCH_LEVEL 0
+#define PATCH_LEVEL 5
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/deps/v8/src/x64/lithium-codegen-x64.cc b/deps/v8/src/x64/lithium-codegen-x64.cc
index 7c70094fbf..31fbcd27ab 100644
--- a/deps/v8/src/x64/lithium-codegen-x64.cc
+++ b/deps/v8/src/x64/lithium-codegen-x64.cc
@@ -5304,6 +5304,11 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
}
+void LCodeGen::DoDummy(LDummy* instr) {
+ // Nothing to see here, move on!
+}
+
+
void LCodeGen::DoDummyUse(LDummyUse* instr) {
// Nothing to see here, move on!
}
diff --git a/deps/v8/src/x64/lithium-x64.cc b/deps/v8/src/x64/lithium-x64.cc
index 6262e7ede3..8f26a09e96 100644
--- a/deps/v8/src/x64/lithium-x64.cc
+++ b/deps/v8/src/x64/lithium-x64.cc
@@ -862,10 +862,12 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
LInstruction* instr = NULL;
if (current->CanReplaceWithDummyUses()) {
- HValue* first_operand = current->OperandCount() == 0
- ? graph()->GetConstant1()
- : current->OperandAt(0);
- instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand)));
+ if (current->OperandCount() == 0) {
+ instr = DefineAsRegister(new(zone()) LDummy());
+ } else {
+ instr = DefineAsRegister(new(zone())
+ LDummyUse(UseAny(current->OperandAt(0))));
+ }
for (int i = 1; i < current->OperandCount(); ++i) {
LInstruction* dummy =
new(zone()) LDummyUse(UseAny(current->OperandAt(i)));
diff --git a/deps/v8/src/x64/lithium-x64.h b/deps/v8/src/x64/lithium-x64.h
index 06cb171923..1a889b3964 100644
--- a/deps/v8/src/x64/lithium-x64.h
+++ b/deps/v8/src/x64/lithium-x64.h
@@ -92,6 +92,7 @@ class LCodeGen;
V(DoubleToSmi) \
V(Drop) \
V(DummyUse) \
+ V(Dummy) \
V(ElementsKind) \
V(ForInCacheArray) \
V(ForInPrepareMap) \
@@ -422,6 +423,13 @@ class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> {
};
+class LDummy V8_FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+ explicit LDummy() { }
+ DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
+};
+
+
class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> {
public:
explicit LDummyUse(LOperand* value) {
diff --git a/deps/v8/src/x64/stub-cache-x64.cc b/deps/v8/src/x64/stub-cache-x64.cc
index 2a0c3675f2..28e2a89627 100644
--- a/deps/v8/src/x64/stub-cache-x64.cc
+++ b/deps/v8/src/x64/stub-cache-x64.cc
@@ -107,38 +107,34 @@ static void ProbeTable(Isolate* isolate,
}
-// Helper function used to check that the dictionary doesn't contain
-// the property. This function may return false negatives, so miss_label
-// must always call a backup property check that is complete.
-// This function is safe to call if the receiver has fast properties.
-// Name must be unique and receiver must be a heap object.
-static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
- Label* miss_label,
- Register receiver,
- Handle<Name> name,
- Register r0,
- Register r1) {
+void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm,
+ Label* miss_label,
+ Register receiver,
+ Handle<Name> name,
+ Register scratch0,
+ Register scratch1) {
ASSERT(name->IsUniqueName());
+ ASSERT(!receiver.is(scratch0));
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->negative_lookups(), 1);
__ IncrementCounter(counters->negative_lookups_miss(), 1);
- __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset));
+ __ movq(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
const int kInterceptorOrAccessCheckNeededMask =
(1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
// Bail out if the receiver has a named interceptor or requires access checks.
- __ testb(FieldOperand(r0, Map::kBitFieldOffset),
+ __ testb(FieldOperand(scratch0, Map::kBitFieldOffset),
Immediate(kInterceptorOrAccessCheckNeededMask));
__ j(not_zero, miss_label);
// Check that receiver is a JSObject.
- __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
+ __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE);
__ j(below, miss_label);
// Load properties array.
- Register properties = r0;
+ Register properties = scratch0;
__ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
// Check that the properties array is a dictionary.
@@ -152,7 +148,7 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
&done,
properties,
name,
- r1);
+ scratch1);
__ bind(&done);
__ DecrementCounter(counters->negative_lookups_miss(), 1);
}
@@ -777,16 +773,13 @@ void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
}
-// Generate code to check that a global property cell is empty. Create
-// the property cell at compilation time if no cell exists for the
-// property.
-static void GenerateCheckPropertyCell(MacroAssembler* masm,
- Handle<GlobalObject> global,
- Handle<Name> name,
- Register scratch,
- Label* miss) {
+void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm,
+ Handle<JSGlobalObject> global,
+ Handle<Name> name,
+ Register scratch,
+ Label* miss) {
Handle<PropertyCell> cell =
- GlobalObject::EnsurePropertyCell(global, name);
+ JSGlobalObject::EnsurePropertyCell(global, name);
ASSERT(cell->value()->IsTheHole());
__ Move(scratch, cell);
__ Cmp(FieldOperand(scratch, Cell::kValueOffset),
@@ -803,7 +796,7 @@ void StoreStubCompiler::GenerateNegativeHolderLookup(
Label* miss) {
if (holder->IsJSGlobalObject()) {
GenerateCheckPropertyCell(
- masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss);
+ masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss);
} else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
GenerateDictionaryNegativeLookup(
masm, miss, holder_reg, name, scratch1(), scratch2());
@@ -1054,19 +1047,17 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
}
-// Calls GenerateCheckPropertyCell for each global object in the prototype chain
-// from object to (but not including) holder.
-static void GenerateCheckPropertyCells(MacroAssembler* masm,
- Handle<JSObject> object,
- Handle<JSObject> holder,
- Handle<Name> name,
- Register scratch,
- Label* miss) {
+void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm,
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<Name> name,
+ Register scratch,
+ Label* miss) {
Handle<JSObject> current = object;
while (!current.is_identical_to(holder)) {
- if (current->IsGlobalObject()) {
+ if (current->IsJSGlobalObject()) {
GenerateCheckPropertyCell(masm,
- Handle<GlobalObject>::cast(current),
+ Handle<JSGlobalObject>::cast(current),
name,
scratch,
miss);
@@ -1282,30 +1273,10 @@ Register LoadStubCompiler::CallbackHandlerFrontend(
}
-void LoadStubCompiler::NonexistentHandlerFrontend(
- Handle<JSObject> object,
- Handle<JSObject> last,
- Handle<Name> name,
- Label* success,
- Handle<GlobalObject> global) {
- Label miss;
-
- HandlerFrontendHeader(object, receiver(), last, name, &miss);
-
- // If the last object in the prototype chain is a global object,
- // check that the global property cell is empty.
- if (!global.is_null()) {
- GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
- }
-
- HandlerFrontendFooter(name, success, &miss);
-}
-
-
void LoadStubCompiler::GenerateLoadField(Register reg,
- Handle<JSObject> holder,
- PropertyIndex field,
- Representation representation) {
+ Handle<JSObject> holder,
+ PropertyIndex field,
+ Representation representation) {
if (!reg.is(receiver())) __ movq(receiver(), reg);
if (kind() == Code::LOAD_IC) {
LoadFieldStub stub(field.is_inobject(holder),
@@ -2957,7 +2928,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
Handle<JSObject> object,
Handle<JSObject> last,
Handle<Name> name,
- Handle<GlobalObject> global) {
+ Handle<JSGlobalObject> global) {
Label success;
NonexistentHandlerFrontend(object, last, name, &success, global);
diff --git a/deps/v8/test/mjsunit/regress/regress-2980.js b/deps/v8/test/mjsunit/regress/regress-2980.js
new file mode 100644
index 0000000000..071a73353a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-2980.js
@@ -0,0 +1,64 @@
+// Copyright 2013 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.
+
+
+function test(expected, holder) {
+ assertEquals(expected, holder.property);
+}
+
+var holder = {}
+holder.__proto__ = null;
+holder.property = "foo";
+delete holder.property;
+test(undefined, holder);
+test(undefined, holder);
+test(undefined, holder);
+holder.property = "bar";
+test("bar", holder);
+test("bar", holder);
+
+// Now the same thing with a nontrivial prototype chain.
+
+function test2(expected, holder) {
+ assertEquals(expected, holder.prop2);
+}
+
+var holder2 = {}
+holder2.prop2 = "foo";
+holder2.__proto__ = null;
+function Receiver() {}
+Receiver.prototype = holder2;
+
+var rec2 = new Receiver();
+delete holder2.prop2;
+
+test2(undefined, rec2);
+test2(undefined, rec2);
+test2(undefined, rec2);
+holder2.prop2 = "bar";
+test2("bar", rec2);
+test2("bar", rec2);
diff --git a/deps/v8/test/mjsunit/regress/regress-298269.js b/deps/v8/test/mjsunit/regress/regress-298269.js
new file mode 100644
index 0000000000..329ff824df
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-298269.js
@@ -0,0 +1,45 @@
+// Copyright 2013 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.
+
+function Cb(a) {
+ var f, g;
+ for(f = a.length; f--;) {
+ g = a.charCodeAt(f);
+ // This will fail after OSR if Runtime_StringCharCodeAt is modified
+ // to iterates optimized frames and visit safepoint pointers.
+ }
+ return g;
+}
+
+var s1 = "long string to make cons string 1";
+var s2 = "long string to make cons string 2";
+Cb(s1 + s2);
+Cb(s1);
+var s3 = "string for triggering osr in Cb";
+for (var i = 0; i < 16; i++) s3 = s3 + s3;
+Cb(s3);
+Cb(s1 + s2); \ No newline at end of file
diff --git a/deps/v8/test/mjsunit/regress/regress-319120.js b/deps/v8/test/mjsunit/regress/regress-319120.js
new file mode 100644
index 0000000000..2899da25d9
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-319120.js
@@ -0,0 +1,28 @@
+// Copyright 2013 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.
+
+assertThrows('x = new Float64Array({length: 0x24924925})');
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-318671.js b/deps/v8/test/mjsunit/regress/regress-crbug-318671.js
new file mode 100644
index 0000000000..54a7d5eeb6
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-318671.js
@@ -0,0 +1,38 @@
+// Copyright 2013 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 add(x, y) { return x + y; }
+
+print(add({ a: 1 }, "a"));
+print(add({ b: 1 }, "b"));
+print(add({ c: 1 }, "c"));
+
+%OptimizeFunctionOnNextCall(add);
+
+print(add("a", 1));