Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/full-codegen/arm/full-codegen-arm.cc b/src/full-codegen/arm/full-codegen-arm.cc
index 91253e3..73e4750 100644
--- a/src/full-codegen/arm/full-codegen-arm.cc
+++ b/src/full-codegen/arm/full-codegen-arm.cc
@@ -540,10 +540,12 @@
true,
true_label_,
false_label_);
- DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable());
- if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
+ DCHECK(lit->IsNull(isolate()) || lit->IsUndefined(isolate()) ||
+ !lit->IsUndetectable());
+ if (lit->IsUndefined(isolate()) || lit->IsNull(isolate()) ||
+ lit->IsFalse(isolate())) {
if (false_label_ != fall_through_) __ b(false_label_);
- } else if (lit->IsTrue() || lit->IsJSObject()) {
+ } else if (lit->IsTrue(isolate()) || lit->IsJSObject()) {
if (true_label_ != fall_through_) __ b(true_label_);
} else if (lit->IsString()) {
if (String::cast(*lit)->length() == 0) {
@@ -799,21 +801,11 @@
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ VariableDeclaration");
+ DCHECK_EQ(VAR, mode);
+ DCHECK(!hole_init);
__ mov(r2, Operand(variable->name()));
- // Declaration nodes are always introduced in one of four modes.
- DCHECK(IsDeclaredVariableMode(mode));
- // Push initial value, if any.
- // Note: For variables we must not push an initial value (such as
- // 'undefined') because we may have a (legal) redeclaration and we
- // must not destroy the current value.
- if (hole_init) {
- __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
- } else {
- __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value.
- }
- __ Push(r2, r0);
- __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- __ CallRuntime(Runtime::kDeclareLookupSlot);
+ __ Push(r2);
+ __ CallRuntime(Runtime::kDeclareEvalVar);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -870,8 +862,7 @@
PushOperand(r2);
// Push initial value for function declaration.
VisitForStackValue(declaration->fun());
- PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
+ CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -1303,14 +1294,14 @@
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
+#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
- __ LoadGlobalObject(LoadDescriptor::ReceiverRegister());
- __ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
- __ mov(LoadDescriptor::SlotRegister(),
+#endif
+ __ mov(LoadGlobalDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
- CallLoadIC(typeof_mode);
+ CallLoadGlobalIC(typeof_mode);
}
@@ -1379,18 +1370,6 @@
}
-void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
- Comment cmnt(masm_, "[ RegExpLiteral");
- __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
- __ mov(r1, Operand(expr->pattern()));
- __ mov(r0, Operand(Smi::FromInt(expr->flags())));
- FastCloneRegExpStub stub(isolate());
- __ CallStub(&stub);
- context()->Plug(r0);
-}
-
-
void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
@@ -1500,12 +1479,16 @@
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->getter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->setter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->setter = property;
}
break;
}
@@ -1524,6 +1507,7 @@
__ mov(r0, Operand(Smi::FromInt(NONE)));
PushOperand(r0);
CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
+ PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1569,6 +1553,8 @@
PushOperand(Smi::FromInt(NONE));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
+ PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
+ BailoutState::NO_REGISTERS);
} else {
DropOperands(3);
}
@@ -1849,7 +1835,7 @@
// When we arrive here, r0 holds the generator object.
__ RecordGeneratorContinuation();
__ ldr(r1, FieldMemOperand(r0, JSGeneratorObject::kResumeModeOffset));
- __ ldr(r0, FieldMemOperand(r0, JSGeneratorObject::kInputOffset));
+ __ ldr(r0, FieldMemOperand(r0, JSGeneratorObject::kInputOrDebugPosOffset));
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
__ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));
@@ -2901,73 +2887,6 @@
}
-void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = r0;
- Register index = r1;
- Register value = r2;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(index, value);
-
- if (FLAG_debug_code) {
- __ SmiTst(value);
- __ Check(eq, kNonSmiValue);
- __ SmiTst(index);
- __ Check(eq, kNonSmiIndex);
- __ SmiUntag(index, index);
- static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
- __ SmiTag(index, index);
- }
-
- __ SmiUntag(value, value);
- __ add(ip,
- string,
- Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
- __ strb(value, MemOperand(ip, index, LSR, kSmiTagSize));
- context()->Plug(string);
-}
-
-
-void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = r0;
- Register index = r1;
- Register value = r2;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(index, value);
-
- if (FLAG_debug_code) {
- __ SmiTst(value);
- __ Check(eq, kNonSmiValue);
- __ SmiTst(index);
- __ Check(eq, kNonSmiIndex);
- __ SmiUntag(index, index);
- static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
- __ SmiTag(index, index);
- }
-
- __ SmiUntag(value, value);
- __ add(ip,
- string,
- Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
- STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
- __ strh(value, MemOperand(ip, index));
- context()->Plug(string);
-}
-
-
void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
@@ -3001,13 +2920,8 @@
Label need_conversion;
Label index_out_of_range;
Label done;
- StringCharCodeAtGenerator generator(object,
- index,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
+ StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
+ &need_conversion, &index_out_of_range);
generator.GenerateFast(masm_);
__ jmp(&done);
@@ -3031,53 +2945,6 @@
}
-void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK(args->length() == 2);
- VisitForStackValue(args->at(0));
- VisitForAccumulatorValue(args->at(1));
-
- Register object = r1;
- Register index = r0;
- Register scratch = r3;
- Register result = r0;
-
- PopOperand(object);
-
- Label need_conversion;
- Label index_out_of_range;
- Label done;
- StringCharAtGenerator generator(object,
- index,
- scratch,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
- generator.GenerateFast(masm_);
- __ jmp(&done);
-
- __ bind(&index_out_of_range);
- // When the index is out of range, the spec requires us to return
- // the empty string.
- __ LoadRoot(result, Heap::kempty_stringRootIndex);
- __ jmp(&done);
-
- __ bind(&need_conversion);
- // Move smi zero into the result register, which will trigger
- // conversion.
- __ mov(result, Operand(Smi::FromInt(0)));
- __ jmp(&done);
-
- NopRuntimeCallHelper call_helper;
- generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
-
- __ bind(&done);
- context()->Plug(result);
-}
-
-
void FullCodeGenerator::EmitCall(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_LE(2, args->length());
@@ -3447,8 +3314,7 @@
}
// Convert old value into a number.
- ToNumberStub convert_stub(isolate());
- __ CallStub(&convert_stub);
+ __ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
// Save result for postfix expressions.
diff --git a/src/full-codegen/arm64/full-codegen-arm64.cc b/src/full-codegen/arm64/full-codegen-arm64.cc
index 61cb141..7848d0d 100644
--- a/src/full-codegen/arm64/full-codegen-arm64.cc
+++ b/src/full-codegen/arm64/full-codegen-arm64.cc
@@ -531,10 +531,12 @@
true,
true_label_,
false_label_);
- DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable());
- if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
+ DCHECK(lit->IsNull(isolate()) || lit->IsUndefined(isolate()) ||
+ !lit->IsUndetectable());
+ if (lit->IsUndefined(isolate()) || lit->IsNull(isolate()) ||
+ lit->IsFalse(isolate())) {
if (false_label_ != fall_through_) __ B(false_label_);
- } else if (lit->IsTrue() || lit->IsJSObject()) {
+ } else if (lit->IsTrue(isolate()) || lit->IsJSObject()) {
if (true_label_ != fall_through_) __ B(true_label_);
} else if (lit->IsString()) {
if (String::cast(*lit)->length() == 0) {
@@ -796,22 +798,11 @@
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ VariableDeclaration");
+ DCHECK_EQ(VAR, mode);
+ DCHECK(!hole_init);
__ Mov(x2, Operand(variable->name()));
- // Declaration nodes are always introduced in one of four modes.
- DCHECK(IsDeclaredVariableMode(mode));
- // Push initial value, if any.
- // Note: For variables we must not push an initial value (such as
- // 'undefined') because we may have a (legal) redeclaration and we
- // must not destroy the current value.
- if (hole_init) {
- __ LoadRoot(x0, Heap::kTheHoleValueRootIndex);
- __ Push(x2, x0);
- } else {
- // Pushing 0 (xzr) indicates no initial value.
- __ Push(x2, xzr);
- }
- __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- __ CallRuntime(Runtime::kDeclareLookupSlot);
+ __ Push(x2);
+ __ CallRuntime(Runtime::kDeclareEvalVar);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -868,8 +859,7 @@
PushOperand(x2);
// Push initial value for function declaration.
VisitForStackValue(declaration->fun());
- PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
+ CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -1288,14 +1278,14 @@
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
+#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
- __ LoadGlobalObject(LoadDescriptor::ReceiverRegister());
- __ Mov(LoadDescriptor::NameRegister(), Operand(var->name()));
- __ Mov(LoadDescriptor::SlotRegister(),
+#endif
+ __ Mov(LoadGlobalDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
- CallLoadIC(typeof_mode);
+ CallLoadGlobalIC(typeof_mode);
}
@@ -1365,18 +1355,6 @@
}
-void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
- Comment cmnt(masm_, "[ RegExpLiteral");
- __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ Mov(x2, Smi::FromInt(expr->literal_index()));
- __ Mov(x1, Operand(expr->pattern()));
- __ Mov(x0, Smi::FromInt(expr->flags()));
- FastCloneRegExpStub stub(isolate());
- __ CallStub(&stub);
- context()->Plug(x0);
-}
-
-
void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
@@ -1484,12 +1462,16 @@
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->getter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->setter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->setter = property;
}
break;
}
@@ -1500,14 +1482,15 @@
for (AccessorTable::Iterator it = accessor_table.begin();
it != accessor_table.end();
++it) {
- __ Peek(x10, 0); // Duplicate receiver.
- PushOperand(x10);
- VisitForStackValue(it->first);
- EmitAccessor(it->second->getter);
- EmitAccessor(it->second->setter);
- __ Mov(x10, Smi::FromInt(NONE));
- PushOperand(x10);
- CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
+ __ Peek(x10, 0); // Duplicate receiver.
+ PushOperand(x10);
+ VisitForStackValue(it->first);
+ EmitAccessor(it->second->getter);
+ EmitAccessor(it->second->setter);
+ __ Mov(x10, Smi::FromInt(NONE));
+ PushOperand(x10);
+ CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
+ PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1553,6 +1536,8 @@
PushOperand(Smi::FromInt(NONE));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
+ PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
+ BailoutState::NO_REGISTERS);
} else {
DropOperands(3);
}
@@ -2809,66 +2794,6 @@
}
-void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = x0;
- Register index = x1;
- Register value = x2;
- Register scratch = x10;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(value, index);
-
- if (FLAG_debug_code) {
- __ AssertSmi(value, kNonSmiValue);
- __ AssertSmi(index, kNonSmiIndex);
- static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch,
- one_byte_seq_type);
- }
-
- __ Add(scratch, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
- __ SmiUntag(value);
- __ SmiUntag(index);
- __ Strb(value, MemOperand(scratch, index));
- context()->Plug(string);
-}
-
-
-void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = x0;
- Register index = x1;
- Register value = x2;
- Register scratch = x10;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(value, index);
-
- if (FLAG_debug_code) {
- __ AssertSmi(value, kNonSmiValue);
- __ AssertSmi(index, kNonSmiIndex);
- static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, kIndexIsSmi, scratch,
- two_byte_seq_type);
- }
-
- __ Add(scratch, string, SeqTwoByteString::kHeaderSize - kHeapObjectTag);
- __ SmiUntag(value);
- __ SmiUntag(index);
- __ Strh(value, MemOperand(scratch, index, LSL, 1));
- context()->Plug(string);
-}
-
-
void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
@@ -2907,13 +2832,8 @@
Label need_conversion;
Label index_out_of_range;
Label done;
- StringCharCodeAtGenerator generator(object,
- index,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
+ StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
+ &need_conversion, &index_out_of_range);
generator.GenerateFast(masm_);
__ B(&done);
@@ -2936,52 +2856,6 @@
}
-void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK(args->length() == 2);
-
- VisitForStackValue(args->at(0));
- VisitForAccumulatorValue(args->at(1));
-
- Register object = x1;
- Register index = x0;
- Register result = x0;
-
- PopOperand(object);
-
- Label need_conversion;
- Label index_out_of_range;
- Label done;
- StringCharAtGenerator generator(object,
- index,
- x3,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
- generator.GenerateFast(masm_);
- __ B(&done);
-
- __ Bind(&index_out_of_range);
- // When the index is out of range, the spec requires us to return
- // the empty string.
- __ LoadRoot(result, Heap::kempty_stringRootIndex);
- __ B(&done);
-
- __ Bind(&need_conversion);
- // Move smi zero into the result register, which will trigger conversion.
- __ Mov(result, Smi::FromInt(0));
- __ B(&done);
-
- NopRuntimeCallHelper call_helper;
- generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
-
- __ Bind(&done);
- context()->Plug(result);
-}
-
-
void FullCodeGenerator::EmitCall(CallRuntime* expr) {
ASM_LOCATION("FullCodeGenerator::EmitCall");
ZoneList<Expression*>* args = expr->arguments();
@@ -3359,8 +3233,7 @@
}
// Convert old value into a number.
- ToNumberStub convert_stub(isolate());
- __ CallStub(&convert_stub);
+ __ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
// Save result for postfix expressions.
@@ -3701,7 +3574,7 @@
// When we arrive here, x0 holds the generator object.
__ RecordGeneratorContinuation();
__ Ldr(x1, FieldMemOperand(x0, JSGeneratorObject::kResumeModeOffset));
- __ Ldr(x0, FieldMemOperand(x0, JSGeneratorObject::kInputOffset));
+ __ Ldr(x0, FieldMemOperand(x0, JSGeneratorObject::kInputOrDebugPosOffset));
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
__ Cmp(x1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));
diff --git a/src/full-codegen/full-codegen.cc b/src/full-codegen/full-codegen.cc
index 2d7ad32..03140c9 100644
--- a/src/full-codegen/full-codegen.cc
+++ b/src/full-codegen/full-codegen.cc
@@ -34,7 +34,8 @@
TRACE_EVENT0("v8", "V8.CompileFullCode");
Handle<Script> script = info->script();
- if (!script->IsUndefined() && !script->source()->IsUndefined()) {
+ if (!script->IsUndefined(isolate) &&
+ !script->source()->IsUndefined(isolate)) {
int len = String::cast(script->source())->length();
isolate->counters()->total_full_codegen_source_size()->Increment(len);
}
@@ -169,13 +170,16 @@
PrepareForBailoutForId(node->id(), state);
}
-
-void FullCodeGenerator::CallLoadIC(TypeofMode typeof_mode,
- TypeFeedbackId id) {
- Handle<Code> ic = CodeFactory::LoadIC(isolate(), typeof_mode).code();
+void FullCodeGenerator::CallLoadIC(TypeFeedbackId id) {
+ Handle<Code> ic = CodeFactory::LoadIC(isolate()).code();
CallIC(ic, id);
}
+void FullCodeGenerator::CallLoadGlobalIC(TypeofMode typeof_mode,
+ TypeFeedbackId id) {
+ Handle<Code> ic = CodeFactory::LoadGlobalIC(isolate(), typeof_mode).code();
+ CallIC(ic, id);
+}
void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) {
Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code();
@@ -611,18 +615,14 @@
RestoreContext();
}
-bool RecordStatementPosition(MacroAssembler* masm, int pos) {
- if (pos == RelocInfo::kNoPosition) return false;
+void RecordStatementPosition(MacroAssembler* masm, int pos) {
+ if (pos == RelocInfo::kNoPosition) return;
masm->positions_recorder()->RecordStatementPosition(pos);
- masm->positions_recorder()->RecordPosition(pos);
- return masm->positions_recorder()->WriteRecordedPositions();
}
-
-bool RecordPosition(MacroAssembler* masm, int pos) {
- if (pos == RelocInfo::kNoPosition) return false;
+void RecordPosition(MacroAssembler* masm, int pos) {
+ if (pos == RelocInfo::kNoPosition) return;
masm->positions_recorder()->RecordPosition(pos);
- return masm->positions_recorder()->WriteRecordedPositions();
}
@@ -646,8 +646,8 @@
void FullCodeGenerator::SetStatementPosition(
Statement* stmt, FullCodeGenerator::InsertBreak insert_break) {
if (stmt->position() == RelocInfo::kNoPosition) return;
- bool recorded = RecordStatementPosition(masm_, stmt->position());
- if (recorded && insert_break == INSERT_BREAK && info_->is_debug() &&
+ RecordStatementPosition(masm_, stmt->position());
+ if (insert_break == INSERT_BREAK && info_->is_debug() &&
!stmt->IsDebuggerStatement()) {
DebugCodegen::GenerateSlot(masm_, RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
}
@@ -661,8 +661,8 @@
void FullCodeGenerator::SetExpressionAsStatementPosition(Expression* expr) {
if (expr->position() == RelocInfo::kNoPosition) return;
- bool recorded = RecordStatementPosition(masm_, expr->position());
- if (recorded && info_->is_debug()) {
+ RecordStatementPosition(masm_, expr->position());
+ if (info_->is_debug()) {
DebugCodegen::GenerateSlot(masm_, RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
}
}
@@ -1032,17 +1032,12 @@
void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
bool pretenure) {
- // Use the fast case closure allocation code that allocates in new
- // space for nested functions that don't need literals cloning. If
- // we're running with the --always-opt or the --prepare-always-opt
+ // If we're running with the --always-opt or the --prepare-always-opt
// flag, we need to use the runtime function so that the new function
// we are creating here gets a chance to have its code optimized and
// doesn't just get a copy of the existing unoptimized code.
- if (!FLAG_always_opt &&
- !FLAG_prepare_always_opt &&
- !pretenure &&
- scope()->is_function_scope() &&
- info->num_literals() == 0) {
+ if (!FLAG_always_opt && !FLAG_prepare_always_opt && !pretenure &&
+ scope()->is_function_scope()) {
FastNewClosureStub stub(isolate(), info->language_mode(), info->kind());
__ Move(stub.GetCallInterfaceDescriptor().GetRegisterParameter(0), info);
__ CallStub(&stub);
@@ -1063,7 +1058,7 @@
__ Move(LoadDescriptor::NameRegister(), key->value());
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
- CallLoadIC(NOT_INSIDE_TYPEOF);
+ CallLoadIC();
}
void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
@@ -1526,7 +1521,7 @@
__ LoadRoot(LoadDescriptor::NameRegister(),
Heap::kprototype_stringRootIndex);
__ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot()));
- CallLoadIC(NOT_INSIDE_TYPEOF);
+ CallLoadIC();
PrepareForBailoutForId(lit->PrototypeId(), BailoutState::TOS_REGISTER);
PushOperand(result_register());
@@ -1545,6 +1540,19 @@
context()->Plug(result_register());
}
+void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
+ Comment cmnt(masm_, "[ RegExpLiteral");
+ Callable callable = CodeFactory::FastCloneRegExp(isolate());
+ CallInterfaceDescriptor descriptor = callable.descriptor();
+ LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset,
+ descriptor.GetRegisterParameter(0));
+ __ Move(descriptor.GetRegisterParameter(1),
+ Smi::FromInt(expr->literal_index()));
+ __ Move(descriptor.GetRegisterParameter(2), expr->pattern());
+ __ Move(descriptor.GetRegisterParameter(3), Smi::FromInt(expr->flags()));
+ __ Call(callable.code(), RelocInfo::CODE_TARGET);
+ context()->Plug(result_register());
+}
void FullCodeGenerator::VisitNativeFunctionLiteral(
NativeFunctionLiteral* expr) {
diff --git a/src/full-codegen/full-codegen.h b/src/full-codegen/full-codegen.h
index 0a004a8..87367ca 100644
--- a/src/full-codegen/full-codegen.h
+++ b/src/full-codegen/full-codegen.h
@@ -512,9 +512,6 @@
F(NewObject) \
F(ValueOf) \
F(StringCharFromCode) \
- F(StringCharAt) \
- F(OneByteSeqStringSetChar) \
- F(TwoByteSeqStringSetChar) \
F(IsJSReceiver) \
F(MathPow) \
F(HasCachedArrayIndex) \
@@ -657,9 +654,10 @@
void CallIC(Handle<Code> code,
TypeFeedbackId id = TypeFeedbackId::None());
+ void CallLoadIC(TypeFeedbackId id = TypeFeedbackId::None());
// Inside typeof reference errors are never thrown.
- void CallLoadIC(TypeofMode typeof_mode,
- TypeFeedbackId id = TypeFeedbackId::None());
+ void CallLoadGlobalIC(TypeofMode typeof_mode,
+ TypeFeedbackId id = TypeFeedbackId::None());
void CallStoreIC(TypeFeedbackId id = TypeFeedbackId::None());
void SetFunctionPosition(FunctionLiteral* fun);
diff --git a/src/full-codegen/ia32/full-codegen-ia32.cc b/src/full-codegen/ia32/full-codegen-ia32.cc
index 760a818..c0f8396 100644
--- a/src/full-codegen/ia32/full-codegen-ia32.cc
+++ b/src/full-codegen/ia32/full-codegen-ia32.cc
@@ -490,10 +490,12 @@
true,
true_label_,
false_label_);
- DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable());
- if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
+ DCHECK(lit->IsNull(isolate()) || lit->IsUndefined(isolate()) ||
+ !lit->IsUndetectable());
+ if (lit->IsUndefined(isolate()) || lit->IsNull(isolate()) ||
+ lit->IsFalse(isolate())) {
if (false_label_ != fall_through_) __ jmp(false_label_);
- } else if (lit->IsTrue() || lit->IsJSObject()) {
+ } else if (lit->IsTrue(isolate()) || lit->IsJSObject()) {
if (true_label_ != fall_through_) __ jmp(true_label_);
} else if (lit->IsString()) {
if (String::cast(*lit)->length() == 0) {
@@ -746,21 +748,10 @@
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ VariableDeclaration");
+ DCHECK_EQ(VAR, mode);
+ DCHECK(!hole_init);
__ push(Immediate(variable->name()));
- // VariableDeclaration nodes are always introduced in one of four modes.
- DCHECK(IsDeclaredVariableMode(mode));
- // Push initial value, if any.
- // Note: For variables we must not push an initial value (such as
- // 'undefined') because we may have a (legal) redeclaration and we
- // must not destroy the current value.
- if (hole_init) {
- __ push(Immediate(isolate()->factory()->the_hole_value()));
- } else {
- __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value.
- }
- __ push(
- Immediate(Smi::FromInt(variable->DeclarationPropertyAttributes())));
- __ CallRuntime(Runtime::kDeclareLookupSlot);
+ __ CallRuntime(Runtime::kDeclareEvalVar);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -813,8 +804,7 @@
Comment cmnt(masm_, "[ FunctionDeclaration");
PushOperand(variable->name());
VisitForStackValue(declaration->fun());
- PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
+ CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -1226,17 +1216,14 @@
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
+#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
- __ mov(LoadDescriptor::ReceiverRegister(), NativeContextOperand());
- __ mov(LoadDescriptor::ReceiverRegister(),
- ContextOperand(LoadDescriptor::ReceiverRegister(),
- Context::EXTENSION_INDEX));
- __ mov(LoadDescriptor::NameRegister(), var->name());
- __ mov(LoadDescriptor::SlotRegister(),
+#endif
+ __ mov(LoadGlobalDescriptor::SlotRegister(),
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
- CallLoadIC(typeof_mode);
+ CallLoadGlobalIC(typeof_mode);
}
@@ -1305,18 +1292,6 @@
}
-void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
- Comment cmnt(masm_, "[ RegExpLiteral");
- __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
- __ Move(eax, Immediate(Smi::FromInt(expr->literal_index())));
- __ Move(ecx, Immediate(expr->pattern()));
- __ Move(edx, Immediate(Smi::FromInt(expr->flags())));
- FastCloneRegExpStub stub(isolate());
- __ CallStub(&stub);
- context()->Plug(eax);
-}
-
-
void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
@@ -1423,12 +1398,16 @@
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->getter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->setter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->setter = property;
}
break;
}
@@ -1447,6 +1426,7 @@
PushOperand(Smi::FromInt(NONE));
CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
+ PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1491,6 +1471,8 @@
PushOperand(Smi::FromInt(NONE));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
+ PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
+ BailoutState::NO_REGISTERS);
} else {
DropOperands(3);
}
@@ -1766,7 +1748,7 @@
// When we arrive here, eax holds the generator object.
__ RecordGeneratorContinuation();
__ mov(ebx, FieldOperand(eax, JSGeneratorObject::kResumeModeOffset));
- __ mov(eax, FieldOperand(eax, JSGeneratorObject::kInputOffset));
+ __ mov(eax, FieldOperand(eax, JSGeneratorObject::kInputOrDebugPosOffset));
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
__ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::kReturn)));
@@ -2791,75 +2773,6 @@
}
-void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = eax;
- Register index = ebx;
- Register value = ecx;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
-
- PopOperand(value);
- PopOperand(index);
-
- if (FLAG_debug_code) {
- __ test(value, Immediate(kSmiTagMask));
- __ Check(zero, kNonSmiValue);
- __ test(index, Immediate(kSmiTagMask));
- __ Check(zero, kNonSmiValue);
- }
-
- __ SmiUntag(value);
- __ SmiUntag(index);
-
- if (FLAG_debug_code) {
- static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
- }
-
- __ mov_b(FieldOperand(string, index, times_1, SeqOneByteString::kHeaderSize),
- value);
- context()->Plug(string);
-}
-
-
-void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = eax;
- Register index = ebx;
- Register value = ecx;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperand(value);
- PopOperand(index);
-
- if (FLAG_debug_code) {
- __ test(value, Immediate(kSmiTagMask));
- __ Check(zero, kNonSmiValue);
- __ test(index, Immediate(kSmiTagMask));
- __ Check(zero, kNonSmiValue);
- __ SmiUntag(index);
- static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
- __ SmiTag(index);
- }
-
- __ SmiUntag(value);
- // No need to untag a smi for two-byte addressing.
- __ mov_w(FieldOperand(string, index, times_1, SeqTwoByteString::kHeaderSize),
- value);
- context()->Plug(string);
-}
-
-
void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
@@ -2895,13 +2808,8 @@
Label need_conversion;
Label index_out_of_range;
Label done;
- StringCharCodeAtGenerator generator(object,
- index,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
+ StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
+ &need_conversion, &index_out_of_range);
generator.GenerateFast(masm_);
__ jmp(&done);
@@ -2925,54 +2833,6 @@
}
-void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK(args->length() == 2);
-
- VisitForStackValue(args->at(0));
- VisitForAccumulatorValue(args->at(1));
-
- Register object = ebx;
- Register index = eax;
- Register scratch = edx;
- Register result = eax;
-
- PopOperand(object);
-
- Label need_conversion;
- Label index_out_of_range;
- Label done;
- StringCharAtGenerator generator(object,
- index,
- scratch,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
- generator.GenerateFast(masm_);
- __ jmp(&done);
-
- __ bind(&index_out_of_range);
- // When the index is out of range, the spec requires us to return
- // the empty string.
- __ Move(result, Immediate(isolate()->factory()->empty_string()));
- __ jmp(&done);
-
- __ bind(&need_conversion);
- // Move smi zero into the result register, which will trigger
- // conversion.
- __ Move(result, Immediate(Smi::FromInt(0)));
- __ jmp(&done);
-
- NopRuntimeCallHelper call_helper;
- generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
-
- __ bind(&done);
- context()->Plug(result);
-}
-
-
void FullCodeGenerator::EmitCall(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_LE(2, args->length());
@@ -3351,8 +3211,7 @@
}
// Convert old value into a number.
- ToNumberStub convert_stub(isolate());
- __ CallStub(&convert_stub);
+ __ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
// Save result for postfix expressions.
diff --git a/src/full-codegen/mips/full-codegen-mips.cc b/src/full-codegen/mips/full-codegen-mips.cc
index e61c3e4..014aaf6 100644
--- a/src/full-codegen/mips/full-codegen-mips.cc
+++ b/src/full-codegen/mips/full-codegen-mips.cc
@@ -531,10 +531,12 @@
true,
true_label_,
false_label_);
- DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable());
- if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
+ DCHECK(lit->IsNull(isolate()) || lit->IsUndefined(isolate()) ||
+ !lit->IsUndetectable());
+ if (lit->IsUndefined(isolate()) || lit->IsNull(isolate()) ||
+ lit->IsFalse(isolate())) {
if (false_label_ != fall_through_) __ Branch(false_label_);
- } else if (lit->IsTrue() || lit->IsJSObject()) {
+ } else if (lit->IsTrue(isolate()) || lit->IsJSObject()) {
if (true_label_ != fall_through_) __ Branch(true_label_);
} else if (lit->IsString()) {
if (String::cast(*lit)->length() == 0) {
@@ -796,22 +798,11 @@
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ VariableDeclaration");
+ DCHECK_EQ(VAR, mode);
+ DCHECK(!hole_init);
__ li(a2, Operand(variable->name()));
- // Declaration nodes are always introduced in one of four modes.
- DCHECK(IsDeclaredVariableMode(mode));
- // Push initial value, if any.
- // Note: For variables we must not push an initial value (such as
- // 'undefined') because we may have a (legal) redeclaration and we
- // must not destroy the current value.
- if (hole_init) {
- __ LoadRoot(a0, Heap::kTheHoleValueRootIndex);
- } else {
- DCHECK(Smi::FromInt(0) == 0);
- __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value.
- }
- __ Push(a2, a0);
- __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- __ CallRuntime(Runtime::kDeclareLookupSlot);
+ __ Push(a2);
+ __ CallRuntime(Runtime::kDeclareEvalVar);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -868,8 +859,7 @@
PushOperand(a2);
// Push initial value for function declaration.
VisitForStackValue(declaration->fun());
- PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
+ CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -1298,14 +1288,14 @@
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
+#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
- __ LoadGlobalObject(LoadDescriptor::ReceiverRegister());
- __ li(LoadDescriptor::NameRegister(), Operand(var->name()));
- __ li(LoadDescriptor::SlotRegister(),
+#endif
+ __ li(LoadGlobalDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
- CallLoadIC(typeof_mode);
+ CallLoadGlobalIC(typeof_mode);
}
@@ -1375,18 +1365,6 @@
}
-void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
- Comment cmnt(masm_, "[ RegExpLiteral");
- __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ li(a2, Operand(Smi::FromInt(expr->literal_index())));
- __ li(a1, Operand(expr->pattern()));
- __ li(a0, Operand(Smi::FromInt(expr->flags())));
- FastCloneRegExpStub stub(isolate());
- __ CallStub(&stub);
- context()->Plug(v0);
-}
-
-
void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
@@ -1495,12 +1473,16 @@
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->getter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->setter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->setter = property;
}
break;
}
@@ -1519,6 +1501,7 @@
__ li(a0, Operand(Smi::FromInt(NONE)));
PushOperand(a0);
CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
+ PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1564,6 +1547,8 @@
PushOperand(Smi::FromInt(NONE));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
+ PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
+ BailoutState::NO_REGISTERS);
} else {
DropOperands(3);
}
@@ -1845,7 +1830,7 @@
// When we arrive here, v0 holds the generator object.
__ RecordGeneratorContinuation();
__ lw(a1, FieldMemOperand(v0, JSGeneratorObject::kResumeModeOffset));
- __ lw(v0, FieldMemOperand(v0, JSGeneratorObject::kInputOffset));
+ __ lw(v0, FieldMemOperand(v0, JSGeneratorObject::kInputOrDebugPosOffset));
__ Branch(&resume, eq, a1, Operand(Smi::FromInt(JSGeneratorObject::kNext)));
__ Push(result_register());
__ Branch(&exception, eq, a1,
@@ -2908,80 +2893,6 @@
}
-void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = v0;
- Register index = a1;
- Register value = a2;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(index, value);
-
- if (FLAG_debug_code) {
- __ SmiTst(value, at);
- __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
- __ SmiTst(index, at);
- __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
- __ SmiUntag(index, index);
- static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
- Register scratch = t5;
- __ EmitSeqStringSetCharCheck(
- string, index, value, scratch, one_byte_seq_type);
- __ SmiTag(index, index);
- }
-
- __ SmiUntag(value, value);
- __ Addu(at,
- string,
- Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
- __ SmiUntag(index);
- __ Addu(at, at, index);
- __ sb(value, MemOperand(at));
- context()->Plug(string);
-}
-
-
-void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = v0;
- Register index = a1;
- Register value = a2;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(index, value);
-
- if (FLAG_debug_code) {
- __ SmiTst(value, at);
- __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
- __ SmiTst(index, at);
- __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
- __ SmiUntag(index, index);
- static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
- Register scratch = t5;
- __ EmitSeqStringSetCharCheck(
- string, index, value, scratch, two_byte_seq_type);
- __ SmiTag(index, index);
- }
-
- __ SmiUntag(value, value);
- __ Addu(at,
- string,
- Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
- __ Addu(at, at, index);
- STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
- __ sh(value, MemOperand(at));
- context()->Plug(string);
-}
-
-
void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
@@ -3018,13 +2929,8 @@
Label need_conversion;
Label index_out_of_range;
Label done;
- StringCharCodeAtGenerator generator(object,
- index,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
+ StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
+ &need_conversion, &index_out_of_range);
generator.GenerateFast(masm_);
__ jmp(&done);
@@ -3048,55 +2954,6 @@
}
-void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK(args->length() == 2);
-
- VisitForStackValue(args->at(0));
- VisitForAccumulatorValue(args->at(1));
- __ mov(a0, result_register());
-
- Register object = a1;
- Register index = a0;
- Register scratch = a3;
- Register result = v0;
-
- PopOperand(object);
-
- Label need_conversion;
- Label index_out_of_range;
- Label done;
- StringCharAtGenerator generator(object,
- index,
- scratch,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
- generator.GenerateFast(masm_);
- __ jmp(&done);
-
- __ bind(&index_out_of_range);
- // When the index is out of range, the spec requires us to return
- // the empty string.
- __ LoadRoot(result, Heap::kempty_stringRootIndex);
- __ jmp(&done);
-
- __ bind(&need_conversion);
- // Move smi zero into the result register, which will trigger
- // conversion.
- __ li(result, Operand(Smi::FromInt(0)));
- __ jmp(&done);
-
- NopRuntimeCallHelper call_helper;
- generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
-
- __ bind(&done);
- context()->Plug(result);
-}
-
-
void FullCodeGenerator::EmitCall(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_LE(2, args->length());
@@ -3466,8 +3323,7 @@
}
// Convert old value into a number.
- ToNumberStub convert_stub(isolate());
- __ CallStub(&convert_stub);
+ __ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
// Save result for postfix expressions.
diff --git a/src/full-codegen/mips64/full-codegen-mips64.cc b/src/full-codegen/mips64/full-codegen-mips64.cc
index a93489d..a58f173 100644
--- a/src/full-codegen/mips64/full-codegen-mips64.cc
+++ b/src/full-codegen/mips64/full-codegen-mips64.cc
@@ -530,10 +530,12 @@
true,
true_label_,
false_label_);
- DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable());
- if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
+ DCHECK(lit->IsNull(isolate()) || lit->IsUndefined(isolate()) ||
+ !lit->IsUndetectable());
+ if (lit->IsUndefined(isolate()) || lit->IsNull(isolate()) ||
+ lit->IsFalse(isolate())) {
if (false_label_ != fall_through_) __ Branch(false_label_);
- } else if (lit->IsTrue() || lit->IsJSObject()) {
+ } else if (lit->IsTrue(isolate()) || lit->IsJSObject()) {
if (true_label_ != fall_through_) __ Branch(true_label_);
} else if (lit->IsString()) {
if (String::cast(*lit)->length() == 0) {
@@ -795,22 +797,11 @@
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ VariableDeclaration");
+ DCHECK_EQ(VAR, mode);
+ DCHECK(!hole_init);
__ li(a2, Operand(variable->name()));
- // Declaration nodes are always introduced in one of four modes.
- DCHECK(IsDeclaredVariableMode(mode));
- // Push initial value, if any.
- // Note: For variables we must not push an initial value (such as
- // 'undefined') because we may have a (legal) redeclaration and we
- // must not destroy the current value.
- if (hole_init) {
- __ LoadRoot(a0, Heap::kTheHoleValueRootIndex);
- } else {
- DCHECK(Smi::FromInt(0) == 0);
- __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value.
- }
- __ Push(a2, a0);
- __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- __ CallRuntime(Runtime::kDeclareLookupSlot);
+ __ Push(a2);
+ __ CallRuntime(Runtime::kDeclareEvalVar);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -867,8 +858,7 @@
PushOperand(a2);
// Push initial value for function declaration.
VisitForStackValue(declaration->fun());
- PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
+ CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -1299,14 +1289,14 @@
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
+#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
- __ LoadGlobalObject(LoadDescriptor::ReceiverRegister());
- __ li(LoadDescriptor::NameRegister(), Operand(var->name()));
- __ li(LoadDescriptor::SlotRegister(),
+#endif
+ __ li(LoadGlobalDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
- CallLoadIC(typeof_mode);
+ CallLoadGlobalIC(typeof_mode);
}
@@ -1376,18 +1366,6 @@
}
-void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
- Comment cmnt(masm_, "[ RegExpLiteral");
- __ ld(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ li(a2, Operand(Smi::FromInt(expr->literal_index())));
- __ li(a1, Operand(expr->pattern()));
- __ li(a0, Operand(Smi::FromInt(expr->flags())));
- FastCloneRegExpStub stub(isolate());
- __ CallStub(&stub);
- context()->Plug(v0);
-}
-
-
void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
@@ -1496,12 +1474,16 @@
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->getter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->setter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->setter = property;
}
break;
}
@@ -1520,6 +1502,7 @@
__ li(a0, Operand(Smi::FromInt(NONE)));
PushOperand(a0);
CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
+ PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1565,6 +1548,8 @@
PushOperand(Smi::FromInt(NONE));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
+ PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
+ BailoutState::NO_REGISTERS);
} else {
DropOperands(3);
}
@@ -1846,7 +1831,7 @@
// When we arrive here, v0 holds the generator object.
__ RecordGeneratorContinuation();
__ ld(a1, FieldMemOperand(v0, JSGeneratorObject::kResumeModeOffset));
- __ ld(v0, FieldMemOperand(v0, JSGeneratorObject::kInputOffset));
+ __ ld(v0, FieldMemOperand(v0, JSGeneratorObject::kInputOrDebugPosOffset));
__ Branch(&resume, eq, a1, Operand(Smi::FromInt(JSGeneratorObject::kNext)));
__ Push(result_register());
__ Branch(&exception, eq, a1,
@@ -2907,81 +2892,6 @@
}
-void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = v0;
- Register index = a1;
- Register value = a2;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(index, value);
-
- if (FLAG_debug_code) {
- __ SmiTst(value, at);
- __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
- __ SmiTst(index, at);
- __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
- __ SmiUntag(index, index);
- static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
- Register scratch = t1;
- __ EmitSeqStringSetCharCheck(
- string, index, value, scratch, one_byte_seq_type);
- __ SmiTag(index, index);
- }
-
- __ SmiUntag(value, value);
- __ Daddu(at,
- string,
- Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
- __ SmiUntag(index);
- __ Daddu(at, at, index);
- __ sb(value, MemOperand(at));
- context()->Plug(string);
-}
-
-
-void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = v0;
- Register index = a1;
- Register value = a2;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(index, value);
-
- if (FLAG_debug_code) {
- __ SmiTst(value, at);
- __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
- __ SmiTst(index, at);
- __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
- __ SmiUntag(index, index);
- static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
- Register scratch = t1;
- __ EmitSeqStringSetCharCheck(
- string, index, value, scratch, two_byte_seq_type);
- __ SmiTag(index, index);
- }
-
- __ SmiUntag(value, value);
- __ Daddu(at,
- string,
- Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
- __ dsra(index, index, 32 - 1);
- __ Daddu(at, at, index);
- STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
- __ sh(value, MemOperand(at));
- context()->Plug(string);
-}
-
-
void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
@@ -3018,13 +2928,8 @@
Label need_conversion;
Label index_out_of_range;
Label done;
- StringCharCodeAtGenerator generator(object,
- index,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
+ StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
+ &need_conversion, &index_out_of_range);
generator.GenerateFast(masm_);
__ jmp(&done);
@@ -3048,55 +2953,6 @@
}
-void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK(args->length() == 2);
-
- VisitForStackValue(args->at(0));
- VisitForAccumulatorValue(args->at(1));
- __ mov(a0, result_register());
-
- Register object = a1;
- Register index = a0;
- Register scratch = a3;
- Register result = v0;
-
- PopOperand(object);
-
- Label need_conversion;
- Label index_out_of_range;
- Label done;
- StringCharAtGenerator generator(object,
- index,
- scratch,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
- generator.GenerateFast(masm_);
- __ jmp(&done);
-
- __ bind(&index_out_of_range);
- // When the index is out of range, the spec requires us to return
- // the empty string.
- __ LoadRoot(result, Heap::kempty_stringRootIndex);
- __ jmp(&done);
-
- __ bind(&need_conversion);
- // Move smi zero into the result register, which will trigger
- // conversion.
- __ li(result, Operand(Smi::FromInt(0)));
- __ jmp(&done);
-
- NopRuntimeCallHelper call_helper;
- generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
-
- __ bind(&done);
- context()->Plug(result);
-}
-
-
void FullCodeGenerator::EmitCall(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_LE(2, args->length());
@@ -3467,8 +3323,7 @@
}
// Convert old value into a number.
- ToNumberStub convert_stub(isolate());
- __ CallStub(&convert_stub);
+ __ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
// Save result for postfix expressions.
diff --git a/src/full-codegen/ppc/OWNERS b/src/full-codegen/ppc/OWNERS
index eb007cb..752e8e3 100644
--- a/src/full-codegen/ppc/OWNERS
+++ b/src/full-codegen/ppc/OWNERS
@@ -3,3 +3,4 @@
joransiu@ca.ibm.com
mbrandy@us.ibm.com
michael_dawson@ca.ibm.com
+bjaideep@ca.ibm.com
diff --git a/src/full-codegen/ppc/full-codegen-ppc.cc b/src/full-codegen/ppc/full-codegen-ppc.cc
index 50248c1..1f47983 100644
--- a/src/full-codegen/ppc/full-codegen-ppc.cc
+++ b/src/full-codegen/ppc/full-codegen-ppc.cc
@@ -516,10 +516,12 @@
void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_,
false_label_);
- DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable());
- if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
+ DCHECK(lit->IsNull(isolate()) || lit->IsUndefined(isolate()) ||
+ !lit->IsUndetectable());
+ if (lit->IsUndefined(isolate()) || lit->IsNull(isolate()) ||
+ lit->IsFalse(isolate())) {
if (false_label_ != fall_through_) __ b(false_label_);
- } else if (lit->IsTrue() || lit->IsJSObject()) {
+ } else if (lit->IsTrue(isolate()) || lit->IsJSObject()) {
if (true_label_ != fall_through_) __ b(true_label_);
} else if (lit->IsString()) {
if (String::cast(*lit)->length() == 0) {
@@ -761,21 +763,11 @@
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ VariableDeclaration");
+ DCHECK_EQ(VAR, mode);
+ DCHECK(!hole_init);
__ mov(r5, Operand(variable->name()));
- // Declaration nodes are always introduced in one of four modes.
- DCHECK(IsDeclaredVariableMode(mode));
- // Push initial value, if any.
- // Note: For variables we must not push an initial value (such as
- // 'undefined') because we may have a (legal) redeclaration and we
- // must not destroy the current value.
- if (hole_init) {
- __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
- } else {
- __ LoadSmiLiteral(r3, Smi::FromInt(0)); // Indicates no initial value.
- }
- __ Push(r5, r3);
- __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- __ CallRuntime(Runtime::kDeclareLookupSlot);
+ __ Push(r5);
+ __ CallRuntime(Runtime::kDeclareEvalVar);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -828,8 +820,7 @@
PushOperand(r5);
// Push initial value for function declaration.
VisitForStackValue(declaration->fun());
- PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
+ CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -1265,14 +1256,14 @@
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
+#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
- __ LoadGlobalObject(LoadDescriptor::ReceiverRegister());
- __ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
- __ mov(LoadDescriptor::SlotRegister(),
+#endif
+ __ mov(LoadGlobalDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
- CallLoadIC(typeof_mode);
+ CallLoadGlobalIC(typeof_mode);
}
@@ -1341,18 +1332,6 @@
}
-void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
- Comment cmnt(masm_, "[ RegExpLiteral");
- __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ LoadSmiLiteral(r5, Smi::FromInt(expr->literal_index()));
- __ mov(r4, Operand(expr->pattern()));
- __ LoadSmiLiteral(r3, Smi::FromInt(expr->flags()));
- FastCloneRegExpStub stub(isolate());
- __ CallStub(&stub);
- context()->Plug(r3);
-}
-
-
void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
@@ -1461,12 +1440,16 @@
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->getter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->setter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->setter = property;
}
break;
}
@@ -1484,6 +1467,7 @@
__ LoadSmiLiteral(r3, Smi::FromInt(NONE));
PushOperand(r3);
CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
+ PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1529,6 +1513,8 @@
PushOperand(Smi::FromInt(NONE));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
+ PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
+ BailoutState::NO_REGISTERS);
} else {
DropOperands(3);
}
@@ -1807,7 +1793,7 @@
// When we arrive here, r3 holds the generator object.
__ RecordGeneratorContinuation();
__ LoadP(r4, FieldMemOperand(r3, JSGeneratorObject::kResumeModeOffset));
- __ LoadP(r3, FieldMemOperand(r3, JSGeneratorObject::kInputOffset));
+ __ LoadP(r3, FieldMemOperand(r3, JSGeneratorObject::kInputOrDebugPosOffset));
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
__ CmpSmiLiteral(r4, Smi::FromInt(JSGeneratorObject::kReturn), r0);
@@ -2898,70 +2884,6 @@
}
-void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = r3;
- Register index = r4;
- Register value = r5;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(index, value);
-
- if (FLAG_debug_code) {
- __ TestIfSmi(value, r0);
- __ Check(eq, kNonSmiValue, cr0);
- __ TestIfSmi(index, r0);
- __ Check(eq, kNonSmiIndex, cr0);
- __ SmiUntag(index, index);
- static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
- __ SmiTag(index, index);
- }
-
- __ SmiUntag(value);
- __ addi(ip, string, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
- __ SmiToByteArrayOffset(r0, index);
- __ stbx(value, MemOperand(ip, r0));
- context()->Plug(string);
-}
-
-
-void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = r3;
- Register index = r4;
- Register value = r5;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(index, value);
-
- if (FLAG_debug_code) {
- __ TestIfSmi(value, r0);
- __ Check(eq, kNonSmiValue, cr0);
- __ TestIfSmi(index, r0);
- __ Check(eq, kNonSmiIndex, cr0);
- __ SmiUntag(index, index);
- static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
- __ SmiTag(index, index);
- }
-
- __ SmiUntag(value);
- __ addi(ip, string, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
- __ SmiToShortArrayOffset(r0, index);
- __ sthx(value, MemOperand(ip, r0));
- context()->Plug(string);
-}
-
-
void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
@@ -2996,8 +2918,7 @@
Label index_out_of_range;
Label done;
StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
- &need_conversion, &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
+ &need_conversion, &index_out_of_range);
generator.GenerateFast(masm_);
__ b(&done);
@@ -3021,48 +2942,6 @@
}
-void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK(args->length() == 2);
- VisitForStackValue(args->at(0));
- VisitForAccumulatorValue(args->at(1));
-
- Register object = r4;
- Register index = r3;
- Register scratch = r6;
- Register result = r3;
-
- PopOperand(object);
-
- Label need_conversion;
- Label index_out_of_range;
- Label done;
- StringCharAtGenerator generator(object, index, scratch, result,
- &need_conversion, &need_conversion,
- &index_out_of_range, STRING_INDEX_IS_NUMBER);
- generator.GenerateFast(masm_);
- __ b(&done);
-
- __ bind(&index_out_of_range);
- // When the index is out of range, the spec requires us to return
- // the empty string.
- __ LoadRoot(result, Heap::kempty_stringRootIndex);
- __ b(&done);
-
- __ bind(&need_conversion);
- // Move smi zero into the result register, which will trigger
- // conversion.
- __ LoadSmiLiteral(result, Smi::FromInt(0));
- __ b(&done);
-
- NopRuntimeCallHelper call_helper;
- generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
-
- __ bind(&done);
- context()->Plug(result);
-}
-
-
void FullCodeGenerator::EmitCall(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_LE(2, args->length());
@@ -3430,8 +3309,7 @@
}
// Convert old value into a number.
- ToNumberStub convert_stub(isolate());
- __ CallStub(&convert_stub);
+ __ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
// Save result for postfix expressions.
diff --git a/src/full-codegen/s390/OWNERS b/src/full-codegen/s390/OWNERS
index eb007cb..752e8e3 100644
--- a/src/full-codegen/s390/OWNERS
+++ b/src/full-codegen/s390/OWNERS
@@ -3,3 +3,4 @@
joransiu@ca.ibm.com
mbrandy@us.ibm.com
michael_dawson@ca.ibm.com
+bjaideep@ca.ibm.com
diff --git a/src/full-codegen/s390/full-codegen-s390.cc b/src/full-codegen/s390/full-codegen-s390.cc
index 0d2107d..ee0b3e3 100644
--- a/src/full-codegen/s390/full-codegen-s390.cc
+++ b/src/full-codegen/s390/full-codegen-s390.cc
@@ -512,10 +512,12 @@
void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_,
false_label_);
- DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable());
- if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
+ DCHECK(lit->IsNull(isolate()) || lit->IsUndefined(isolate()) ||
+ !lit->IsUndetectable());
+ if (lit->IsUndefined(isolate()) || lit->IsNull(isolate()) ||
+ lit->IsFalse(isolate())) {
if (false_label_ != fall_through_) __ b(false_label_);
- } else if (lit->IsTrue() || lit->IsJSObject()) {
+ } else if (lit->IsTrue(isolate()) || lit->IsJSObject()) {
if (true_label_ != fall_through_) __ b(true_label_);
} else if (lit->IsString()) {
if (String::cast(*lit)->length() == 0) {
@@ -739,21 +741,11 @@
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ VariableDeclaration");
+ DCHECK_EQ(VAR, mode);
+ DCHECK(!hole_init);
__ mov(r4, Operand(variable->name()));
- // Declaration nodes are always introduced in one of four modes.
- DCHECK(IsDeclaredVariableMode(mode));
- // Push initial value, if any.
- // Note: For variables we must not push an initial value (such as
- // 'undefined') because we may have a (legal) redeclaration and we
- // must not destroy the current value.
- if (hole_init) {
- __ LoadRoot(r2, Heap::kTheHoleValueRootIndex);
- } else {
- __ LoadSmiLiteral(r2, Smi::FromInt(0)); // Indicates no initial value.
- }
- __ Push(r4, r2);
- __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- __ CallRuntime(Runtime::kDeclareLookupSlot);
+ __ Push(r4);
+ __ CallRuntime(Runtime::kDeclareEvalVar);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -804,8 +796,7 @@
PushOperand(r4);
// Push initial value for function declaration.
VisitForStackValue(declaration->fun());
- PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
+ CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -1229,14 +1220,14 @@
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
+#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
- __ LoadGlobalObject(LoadDescriptor::ReceiverRegister());
- __ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
- __ mov(LoadDescriptor::SlotRegister(),
+#endif
+ __ mov(LoadGlobalDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
- CallLoadIC(typeof_mode);
+ CallLoadGlobalIC(typeof_mode);
}
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
@@ -1303,17 +1294,6 @@
}
}
-void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
- Comment cmnt(masm_, "[ RegExpLiteral");
- __ LoadP(r5, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ LoadSmiLiteral(r4, Smi::FromInt(expr->literal_index()));
- __ mov(r3, Operand(expr->pattern()));
- __ LoadSmiLiteral(r2, Smi::FromInt(expr->flags()));
- FastCloneRegExpStub stub(isolate());
- __ CallStub(&stub);
- context()->Plug(r2);
-}
-
void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
@@ -1421,12 +1401,16 @@
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->getter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->setter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->setter = property;
}
break;
}
@@ -1444,6 +1428,7 @@
__ LoadSmiLiteral(r2, Smi::FromInt(NONE));
PushOperand(r2);
CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
+ PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1489,6 +1474,8 @@
PushOperand(Smi::FromInt(NONE));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
+ PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
+ BailoutState::NO_REGISTERS);
} else {
DropOperands(3);
}
@@ -1764,7 +1751,7 @@
// When we arrive here, r2 holds the generator object.
__ RecordGeneratorContinuation();
__ LoadP(r3, FieldMemOperand(r2, JSGeneratorObject::kResumeModeOffset));
- __ LoadP(r2, FieldMemOperand(r2, JSGeneratorObject::kInputOffset));
+ __ LoadP(r2, FieldMemOperand(r2, JSGeneratorObject::kInputOrDebugPosOffset));
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
__ CmpSmiLiteral(r3, Smi::FromInt(JSGeneratorObject::kReturn), r0);
@@ -2828,68 +2815,6 @@
context()->Plug(r2);
}
-void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = r2;
- Register index = r3;
- Register value = r4;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(index, value);
-
- if (FLAG_debug_code) {
- __ TestIfSmi(value);
- __ Check(eq, kNonSmiValue, cr0);
- __ TestIfSmi(index);
- __ Check(eq, kNonSmiIndex, cr0);
- __ SmiUntag(index);
- static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
- __ SmiTag(index);
- }
-
- __ SmiUntag(value);
- __ AddP(ip, string, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
- __ SmiToByteArrayOffset(r1, index);
- __ StoreByte(value, MemOperand(ip, r1));
- context()->Plug(string);
-}
-
-void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = r2;
- Register index = r3;
- Register value = r4;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperands(index, value);
-
- if (FLAG_debug_code) {
- __ TestIfSmi(value);
- __ Check(eq, kNonSmiValue, cr0);
- __ TestIfSmi(index);
- __ Check(eq, kNonSmiIndex, cr0);
- __ SmiUntag(index, index);
- static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
- __ SmiTag(index, index);
- }
-
- __ SmiUntag(value);
- __ SmiToShortArrayOffset(r1, index);
- __ StoreHalfWord(value, MemOperand(r1, string, SeqTwoByteString::kHeaderSize -
- kHeapObjectTag));
- context()->Plug(string);
-}
-
void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
@@ -2923,8 +2848,7 @@
Label index_out_of_range;
Label done;
StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
- &need_conversion, &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
+ &need_conversion, &index_out_of_range);
generator.GenerateFast(masm_);
__ b(&done);
@@ -2947,47 +2871,6 @@
context()->Plug(result);
}
-void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK(args->length() == 2);
- VisitForStackValue(args->at(0));
- VisitForAccumulatorValue(args->at(1));
-
- Register object = r3;
- Register index = r2;
- Register scratch = r5;
- Register result = r2;
-
- PopOperand(object);
-
- Label need_conversion;
- Label index_out_of_range;
- Label done;
- StringCharAtGenerator generator(object, index, scratch, result,
- &need_conversion, &need_conversion,
- &index_out_of_range, STRING_INDEX_IS_NUMBER);
- generator.GenerateFast(masm_);
- __ b(&done);
-
- __ bind(&index_out_of_range);
- // When the index is out of range, the spec requires us to return
- // the empty string.
- __ LoadRoot(result, Heap::kempty_stringRootIndex);
- __ b(&done);
-
- __ bind(&need_conversion);
- // Move smi zero into the result register, which will trigger
- // conversion.
- __ LoadSmiLiteral(result, Smi::FromInt(0));
- __ b(&done);
-
- NopRuntimeCallHelper call_helper;
- generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
-
- __ bind(&done);
- context()->Plug(result);
-}
-
void FullCodeGenerator::EmitCall(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_LE(2, args->length());
@@ -3345,8 +3228,7 @@
}
// Convert old value into a number.
- ToNumberStub convert_stub(isolate());
- __ CallStub(&convert_stub);
+ __ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
// Save result for postfix expressions.
diff --git a/src/full-codegen/x64/full-codegen-x64.cc b/src/full-codegen/x64/full-codegen-x64.cc
index 1ef9cee..eabb2f1 100644
--- a/src/full-codegen/x64/full-codegen-x64.cc
+++ b/src/full-codegen/x64/full-codegen-x64.cc
@@ -504,10 +504,12 @@
true,
true_label_,
false_label_);
- DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable());
- if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
+ DCHECK(lit->IsNull(isolate()) || lit->IsUndefined(isolate()) ||
+ !lit->IsUndetectable());
+ if (lit->IsUndefined(isolate()) || lit->IsNull(isolate()) ||
+ lit->IsFalse(isolate())) {
if (false_label_ != fall_through_) __ jmp(false_label_);
- } else if (lit->IsTrue() || lit->IsJSObject()) {
+ } else if (lit->IsTrue(isolate()) || lit->IsJSObject()) {
if (true_label_ != fall_through_) __ jmp(true_label_);
} else if (lit->IsString()) {
if (String::cast(*lit)->length() == 0) {
@@ -758,20 +760,10 @@
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ VariableDeclaration");
+ DCHECK_EQ(VAR, mode);
+ DCHECK(!hole_init);
__ Push(variable->name());
- // Declaration nodes are always introduced in one of four modes.
- DCHECK(IsDeclaredVariableMode(mode));
- // Push initial value, if any.
- // Note: For variables we must not push an initial value (such as
- // 'undefined') because we may have a (legal) redeclaration and we
- // must not destroy the current value.
- if (hole_init) {
- __ PushRoot(Heap::kTheHoleValueRootIndex);
- } else {
- __ Push(Smi::FromInt(0)); // Indicates no initial value.
- }
- __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- __ CallRuntime(Runtime::kDeclareLookupSlot);
+ __ CallRuntime(Runtime::kDeclareEvalVar);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -825,8 +817,7 @@
Comment cmnt(masm_, "[ FunctionDeclaration");
PushOperand(variable->name());
VisitForStackValue(declaration->fun());
- PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
+ CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -1255,14 +1246,14 @@
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
+#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
- __ Move(LoadDescriptor::NameRegister(), var->name());
- __ LoadGlobalObject(LoadDescriptor::ReceiverRegister());
- __ Move(LoadDescriptor::SlotRegister(),
+#endif
+ __ Move(LoadGlobalDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
- CallLoadIC(typeof_mode);
+ CallLoadGlobalIC(typeof_mode);
}
@@ -1331,18 +1322,6 @@
}
-void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
- Comment cmnt(masm_, "[ RegExpLiteral");
- __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
- __ Move(rax, Smi::FromInt(expr->literal_index()));
- __ Move(rcx, expr->pattern());
- __ Move(rdx, Smi::FromInt(expr->flags()));
- FastCloneRegExpStub stub(isolate());
- __ CallStub(&stub);
- context()->Plug(rax);
-}
-
-
void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
@@ -1449,12 +1428,16 @@
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->getter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->setter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->setter = property;
}
break;
}
@@ -1471,6 +1454,7 @@
EmitAccessor(it->second->setter);
PushOperand(Smi::FromInt(NONE));
CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
+ PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1515,6 +1499,8 @@
PushOperand(Smi::FromInt(NONE));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
+ PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
+ BailoutState::NO_REGISTERS);
} else {
DropOperands(3);
}
@@ -1789,7 +1775,7 @@
// When we arrive here, rax holds the generator object.
__ RecordGeneratorContinuation();
__ movp(rbx, FieldOperand(rax, JSGeneratorObject::kResumeModeOffset));
- __ movp(rax, FieldOperand(rax, JSGeneratorObject::kInputOffset));
+ __ movp(rax, FieldOperand(rax, JSGeneratorObject::kInputOrDebugPosOffset));
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
__ SmiCompare(rbx, Smi::FromInt(JSGeneratorObject::kReturn));
@@ -2780,72 +2766,6 @@
}
-void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = rax;
- Register index = rbx;
- Register value = rcx;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperand(value);
- PopOperand(index);
-
- if (FLAG_debug_code) {
- __ Check(__ CheckSmi(value), kNonSmiValue);
- __ Check(__ CheckSmi(index), kNonSmiValue);
- }
-
- __ SmiToInteger32(value, value);
- __ SmiToInteger32(index, index);
-
- if (FLAG_debug_code) {
- static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
- }
-
- __ movb(FieldOperand(string, index, times_1, SeqOneByteString::kHeaderSize),
- value);
- context()->Plug(string);
-}
-
-
-void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = rax;
- Register index = rbx;
- Register value = rcx;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperand(value);
- PopOperand(index);
-
- if (FLAG_debug_code) {
- __ Check(__ CheckSmi(value), kNonSmiValue);
- __ Check(__ CheckSmi(index), kNonSmiValue);
- }
-
- __ SmiToInteger32(value, value);
- __ SmiToInteger32(index, index);
-
- if (FLAG_debug_code) {
- static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
- }
-
- __ movw(FieldOperand(string, index, times_2, SeqTwoByteString::kHeaderSize),
- value);
- context()->Plug(rax);
-}
-
-
void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
@@ -2881,13 +2801,8 @@
Label need_conversion;
Label index_out_of_range;
Label done;
- StringCharCodeAtGenerator generator(object,
- index,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
+ StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
+ &need_conversion, &index_out_of_range);
generator.GenerateFast(masm_);
__ jmp(&done);
@@ -2911,54 +2826,6 @@
}
-void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK(args->length() == 2);
-
- VisitForStackValue(args->at(0));
- VisitForAccumulatorValue(args->at(1));
-
- Register object = rbx;
- Register index = rax;
- Register scratch = rdx;
- Register result = rax;
-
- PopOperand(object);
-
- Label need_conversion;
- Label index_out_of_range;
- Label done;
- StringCharAtGenerator generator(object,
- index,
- scratch,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
- generator.GenerateFast(masm_);
- __ jmp(&done);
-
- __ bind(&index_out_of_range);
- // When the index is out of range, the spec requires us to return
- // the empty string.
- __ LoadRoot(result, Heap::kempty_stringRootIndex);
- __ jmp(&done);
-
- __ bind(&need_conversion);
- // Move smi zero into the result register, which will trigger
- // conversion.
- __ Move(result, Smi::FromInt(0));
- __ jmp(&done);
-
- NopRuntimeCallHelper call_helper;
- generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
-
- __ bind(&done);
- context()->Plug(result);
-}
-
-
void FullCodeGenerator::EmitCall(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_LE(2, args->length());
@@ -3335,8 +3202,7 @@
}
// Convert old value into a number.
- ToNumberStub convert_stub(isolate());
- __ CallStub(&convert_stub);
+ __ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
// Save result for postfix expressions.
diff --git a/src/full-codegen/x87/full-codegen-x87.cc b/src/full-codegen/x87/full-codegen-x87.cc
index d7403fa..2fb9961 100644
--- a/src/full-codegen/x87/full-codegen-x87.cc
+++ b/src/full-codegen/x87/full-codegen-x87.cc
@@ -487,10 +487,12 @@
true,
true_label_,
false_label_);
- DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable());
- if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
+ DCHECK(lit->IsNull(isolate()) || lit->IsUndefined(isolate()) ||
+ !lit->IsUndetectable());
+ if (lit->IsUndefined(isolate()) || lit->IsNull(isolate()) ||
+ lit->IsFalse(isolate())) {
if (false_label_ != fall_through_) __ jmp(false_label_);
- } else if (lit->IsTrue() || lit->IsJSObject()) {
+ } else if (lit->IsTrue(isolate()) || lit->IsJSObject()) {
if (true_label_ != fall_through_) __ jmp(true_label_);
} else if (lit->IsString()) {
if (String::cast(*lit)->length() == 0) {
@@ -743,21 +745,10 @@
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ VariableDeclaration");
+ DCHECK_EQ(VAR, mode);
+ DCHECK(!hole_init);
__ push(Immediate(variable->name()));
- // VariableDeclaration nodes are always introduced in one of four modes.
- DCHECK(IsDeclaredVariableMode(mode));
- // Push initial value, if any.
- // Note: For variables we must not push an initial value (such as
- // 'undefined') because we may have a (legal) redeclaration and we
- // must not destroy the current value.
- if (hole_init) {
- __ push(Immediate(isolate()->factory()->the_hole_value()));
- } else {
- __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value.
- }
- __ push(
- Immediate(Smi::FromInt(variable->DeclarationPropertyAttributes())));
- __ CallRuntime(Runtime::kDeclareLookupSlot);
+ __ CallRuntime(Runtime::kDeclareEvalVar);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -805,8 +796,7 @@
Comment cmnt(masm_, "[ FunctionDeclaration");
PushOperand(variable->name());
VisitForStackValue(declaration->fun());
- PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
+ CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -1218,17 +1208,14 @@
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
+#ifdef DEBUG
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
- __ mov(LoadDescriptor::ReceiverRegister(), NativeContextOperand());
- __ mov(LoadDescriptor::ReceiverRegister(),
- ContextOperand(LoadDescriptor::ReceiverRegister(),
- Context::EXTENSION_INDEX));
- __ mov(LoadDescriptor::NameRegister(), var->name());
- __ mov(LoadDescriptor::SlotRegister(),
+#endif
+ __ mov(LoadGlobalDescriptor::SlotRegister(),
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
- CallLoadIC(typeof_mode);
+ CallLoadGlobalIC(typeof_mode);
}
@@ -1297,18 +1284,6 @@
}
-void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
- Comment cmnt(masm_, "[ RegExpLiteral");
- __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
- __ Move(eax, Immediate(Smi::FromInt(expr->literal_index())));
- __ Move(ecx, Immediate(expr->pattern()));
- __ Move(edx, Immediate(Smi::FromInt(expr->flags())));
- FastCloneRegExpStub stub(isolate());
- __ CallStub(&stub);
- context()->Plug(eax);
-}
-
-
void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
@@ -1415,12 +1390,16 @@
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->getter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
- accessor_table.lookup(key)->second->setter = property;
+ AccessorTable::Iterator it = accessor_table.lookup(key);
+ it->second->bailout_id = expr->GetIdForPropertySet(property_index);
+ it->second->setter = property;
}
break;
}
@@ -1439,6 +1418,7 @@
PushOperand(Smi::FromInt(NONE));
CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
+ PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1483,6 +1463,8 @@
PushOperand(Smi::FromInt(NONE));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
+ PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
+ BailoutState::NO_REGISTERS);
} else {
DropOperands(3);
}
@@ -1758,7 +1740,7 @@
// When we arrive here, eax holds the generator object.
__ RecordGeneratorContinuation();
__ mov(ebx, FieldOperand(eax, JSGeneratorObject::kResumeModeOffset));
- __ mov(eax, FieldOperand(eax, JSGeneratorObject::kInputOffset));
+ __ mov(eax, FieldOperand(eax, JSGeneratorObject::kInputOrDebugPosOffset));
STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
__ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::kReturn)));
@@ -2783,75 +2765,6 @@
}
-void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = eax;
- Register index = ebx;
- Register value = ecx;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
-
- PopOperand(value);
- PopOperand(index);
-
- if (FLAG_debug_code) {
- __ test(value, Immediate(kSmiTagMask));
- __ Check(zero, kNonSmiValue);
- __ test(index, Immediate(kSmiTagMask));
- __ Check(zero, kNonSmiValue);
- }
-
- __ SmiUntag(value);
- __ SmiUntag(index);
-
- if (FLAG_debug_code) {
- static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
- }
-
- __ mov_b(FieldOperand(string, index, times_1, SeqOneByteString::kHeaderSize),
- value);
- context()->Plug(string);
-}
-
-
-void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(3, args->length());
-
- Register string = eax;
- Register index = ebx;
- Register value = ecx;
-
- VisitForStackValue(args->at(0)); // index
- VisitForStackValue(args->at(1)); // value
- VisitForAccumulatorValue(args->at(2)); // string
- PopOperand(value);
- PopOperand(index);
-
- if (FLAG_debug_code) {
- __ test(value, Immediate(kSmiTagMask));
- __ Check(zero, kNonSmiValue);
- __ test(index, Immediate(kSmiTagMask));
- __ Check(zero, kNonSmiValue);
- __ SmiUntag(index);
- static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
- __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
- __ SmiTag(index);
- }
-
- __ SmiUntag(value);
- // No need to untag a smi for two-byte addressing.
- __ mov_w(FieldOperand(string, index, times_1, SeqTwoByteString::kHeaderSize),
- value);
- context()->Plug(string);
-}
-
-
void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
@@ -2887,13 +2800,8 @@
Label need_conversion;
Label index_out_of_range;
Label done;
- StringCharCodeAtGenerator generator(object,
- index,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
+ StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
+ &need_conversion, &index_out_of_range);
generator.GenerateFast(masm_);
__ jmp(&done);
@@ -2917,54 +2825,6 @@
}
-void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK(args->length() == 2);
-
- VisitForStackValue(args->at(0));
- VisitForAccumulatorValue(args->at(1));
-
- Register object = ebx;
- Register index = eax;
- Register scratch = edx;
- Register result = eax;
-
- PopOperand(object);
-
- Label need_conversion;
- Label index_out_of_range;
- Label done;
- StringCharAtGenerator generator(object,
- index,
- scratch,
- result,
- &need_conversion,
- &need_conversion,
- &index_out_of_range,
- STRING_INDEX_IS_NUMBER);
- generator.GenerateFast(masm_);
- __ jmp(&done);
-
- __ bind(&index_out_of_range);
- // When the index is out of range, the spec requires us to return
- // the empty string.
- __ Move(result, Immediate(isolate()->factory()->empty_string()));
- __ jmp(&done);
-
- __ bind(&need_conversion);
- // Move smi zero into the result register, which will trigger
- // conversion.
- __ Move(result, Immediate(Smi::FromInt(0)));
- __ jmp(&done);
-
- NopRuntimeCallHelper call_helper;
- generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
-
- __ bind(&done);
- context()->Plug(result);
-}
-
-
void FullCodeGenerator::EmitCall(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK_LE(2, args->length());
@@ -3343,8 +3203,7 @@
}
// Convert old value into a number.
- ToNumberStub convert_stub(isolate());
- __ CallStub(&convert_stub);
+ __ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
// Save result for postfix expressions.