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/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index a42da50..8a05777 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -62,10 +62,11 @@
size_t index = GetDispatchTableIndex(Bytecode::k##Name, operand_scale); \
dispatch_table_[index] = code->entry(); \
TraceCodegen(code); \
- LOG_CODE_EVENT( \
+ PROFILE( \
isolate_, \
CodeCreateEvent( \
- Logger::BYTECODE_HANDLER_TAG, AbstractCode::cast(*code), \
+ CodeEventListener::BYTECODE_HANDLER_TAG, \
+ AbstractCode::cast(*code), \
Bytecodes::ToString(Bytecode::k##Name, operand_scale).c_str())); \
} \
}
@@ -180,9 +181,8 @@
bool Interpreter::IsDispatchTableInitialized() {
if (FLAG_trace_ignition || FLAG_trace_ignition_codegen ||
FLAG_trace_ignition_dispatches) {
- // Regenerate table to add bytecode tracing operations,
- // print the assembly code generated by TurboFan,
- // or instrument handlers with dispatch counters.
+ // Regenerate table to add bytecode tracing operations, print the assembly
+ // code generated by TurboFan or instrument handlers with dispatch counters.
return false;
}
return dispatch_table_[0] != nullptr;
@@ -250,7 +250,8 @@
NewStringType::kNormal)
.ToLocalChecked();
Local<v8::Number> counter_object = v8::Number::New(isolate, counter);
- CHECK(counters_row->Set(context, to_name_object, counter_object)
+ CHECK(counters_row
+ ->DefineOwnProperty(context, to_name_object, counter_object)
.IsJust());
}
}
@@ -261,7 +262,9 @@
NewStringType::kNormal)
.ToLocalChecked();
- CHECK(counters_map->Set(context, from_name_object, counters_row).IsJust());
+ CHECK(
+ counters_map->DefineOwnProperty(context, from_name_object, counters_row)
+ .IsJust());
}
return counters_map;
@@ -286,19 +289,14 @@
__ Dispatch();
}
-void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) {
- Node* index = __ BytecodeOperandIdx(0);
- Node* constant = __ LoadConstantPoolEntry(index);
- __ SetAccumulator(constant);
- __ Dispatch();
-}
-
-
// LdaConstant <idx>
//
// Load constant literal at |idx| in the constant pool into the accumulator.
void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) {
- DoLoadConstant(assembler);
+ Node* index = __ BytecodeOperandIdx(0);
+ Node* constant = __ LoadConstantPoolEntry(index);
+ __ SetAccumulator(constant);
+ __ Dispatch();
}
// LdaUndefined
@@ -311,6 +309,16 @@
__ Dispatch();
}
+// LdrUndefined <reg>
+//
+// Loads undefined into the accumulator and |reg|.
+void Interpreter::DoLdrUndefined(InterpreterAssembler* assembler) {
+ Node* undefined_value =
+ __ HeapConstant(isolate_->factory()->undefined_value());
+ Node* destination = __ BytecodeOperandReg(0);
+ __ StoreRegister(undefined_value, destination);
+ __ Dispatch();
+}
// LdaNull
//
@@ -321,7 +329,6 @@
__ Dispatch();
}
-
// LdaTheHole
//
// Load TheHole into the accumulator.
@@ -331,7 +338,6 @@
__ Dispatch();
}
-
// LdaTrue
//
// Load True into the accumulator.
@@ -341,7 +347,6 @@
__ Dispatch();
}
-
// LdaFalse
//
// Load False into the accumulator.
@@ -351,7 +356,6 @@
__ Dispatch();
}
-
// Ldar <src>
//
// Load accumulator with value from register <src>.
@@ -362,7 +366,6 @@
__ Dispatch();
}
-
// Star <dst>
//
// Store accumulator to register <dst>.
@@ -373,7 +376,6 @@
__ Dispatch();
}
-
// Mov <src> <dst>
//
// Stores the value of register <src> to register <dst>.
@@ -385,48 +387,58 @@
__ Dispatch();
}
-
-void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) {
+Node* Interpreter::BuildLoadGlobal(Callable ic,
+ InterpreterAssembler* assembler) {
// Get the global object.
Node* context = __ GetContext();
- Node* native_context =
- __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX);
- Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX);
- // Load the global via the LoadIC.
+ // Load the global via the LoadGlobalIC.
Node* code_target = __ HeapConstant(ic.code());
- Node* constant_index = __ BytecodeOperandIdx(0);
- Node* name = __ LoadConstantPoolEntry(constant_index);
- Node* raw_slot = __ BytecodeOperandIdx(1);
+ Node* raw_slot = __ BytecodeOperandIdx(0);
Node* smi_slot = __ SmiTag(raw_slot);
Node* type_feedback_vector = __ LoadTypeFeedbackVector();
- Node* result = __ CallStub(ic.descriptor(), code_target, context, global,
- name, smi_slot, type_feedback_vector);
- __ SetAccumulator(result);
- __ Dispatch();
+ return __ CallStub(ic.descriptor(), code_target, context, smi_slot,
+ type_feedback_vector);
}
-// LdaGlobal <name_index> <slot>
+// LdaGlobal <slot>
//
// Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> outside of a typeof.
void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) {
- Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
- UNINITIALIZED);
- DoLoadGlobal(ic, assembler);
+ Callable ic =
+ CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF);
+ Node* result = BuildLoadGlobal(ic, assembler);
+ __ SetAccumulator(result);
+ __ Dispatch();
}
-// LdaGlobalInsideTypeof <name_index> <slot>
+// LdrGlobal <slot> <reg>
+//
+// Load the global with name in constant pool entry <name_index> into
+// register <reg> using FeedBackVector slot <slot> outside of a typeof.
+void Interpreter::DoLdrGlobal(InterpreterAssembler* assembler) {
+ Callable ic =
+ CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF);
+ Node* result = BuildLoadGlobal(ic, assembler);
+ Node* destination = __ BytecodeOperandReg(1);
+ __ StoreRegister(result, destination);
+ __ Dispatch();
+}
+
+// LdaGlobalInsideTypeof <slot>
//
// Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> inside of a typeof.
void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) {
- Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF,
- UNINITIALIZED);
- DoLoadGlobal(ic, assembler);
+ Callable ic =
+ CodeFactory::LoadGlobalICInOptimizedCode(isolate_, INSIDE_TYPEOF);
+ Node* result = BuildLoadGlobal(ic, assembler);
+ __ SetAccumulator(result);
+ __ Dispatch();
}
-void Interpreter::DoStoreGlobal(Callable ic, InterpreterAssembler* assembler) {
+void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) {
// Get the global object.
Node* context = __ GetContext();
Node* native_context =
@@ -446,40 +458,51 @@
__ Dispatch();
}
-
// StaGlobalSloppy <name_index> <slot>
//
// Store the value in the accumulator into the global with name in constant pool
// entry <name_index> using FeedBackVector slot <slot> in sloppy mode.
void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) {
- Callable ic =
- CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
- DoStoreGlobal(ic, assembler);
+ Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY);
+ DoStaGlobal(ic, assembler);
}
-
// StaGlobalStrict <name_index> <slot>
//
// Store the value in the accumulator into the global with name in constant pool
// entry <name_index> using FeedBackVector slot <slot> in strict mode.
void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) {
- Callable ic =
- CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
- DoStoreGlobal(ic, assembler);
+ Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, STRICT);
+ DoStaGlobal(ic, assembler);
+}
+
+compiler::Node* Interpreter::BuildLoadContextSlot(
+ InterpreterAssembler* assembler) {
+ Node* reg_index = __ BytecodeOperandReg(0);
+ Node* context = __ LoadRegister(reg_index);
+ Node* slot_index = __ BytecodeOperandIdx(1);
+ return __ LoadContextSlot(context, slot_index);
}
// LdaContextSlot <context> <slot_index>
//
// Load the object in |slot_index| of |context| into the accumulator.
void Interpreter::DoLdaContextSlot(InterpreterAssembler* assembler) {
- Node* reg_index = __ BytecodeOperandReg(0);
- Node* context = __ LoadRegister(reg_index);
- Node* slot_index = __ BytecodeOperandIdx(1);
- Node* result = __ LoadContextSlot(context, slot_index);
+ Node* result = BuildLoadContextSlot(assembler);
__ SetAccumulator(result);
__ Dispatch();
}
+// LdrContextSlot <context> <slot_index> <reg>
+//
+// Load the object in <slot_index> of <context> into register <reg>.
+void Interpreter::DoLdrContextSlot(InterpreterAssembler* assembler) {
+ Node* result = BuildLoadContextSlot(assembler);
+ Node* destination = __ BytecodeOperandReg(2);
+ __ StoreRegister(result, destination);
+ __ Dispatch();
+}
+
// StaContextSlot <context> <slot_index>
//
// Stores the object in the accumulator into |slot_index| of |context|.
@@ -492,8 +515,8 @@
__ Dispatch();
}
-void Interpreter::DoLoadLookupSlot(Runtime::FunctionId function_id,
- InterpreterAssembler* assembler) {
+void Interpreter::DoLdaLookupSlot(Runtime::FunctionId function_id,
+ InterpreterAssembler* assembler) {
Node* index = __ BytecodeOperandIdx(0);
Node* name = __ LoadConstantPoolEntry(index);
Node* context = __ GetContext();
@@ -507,7 +530,7 @@
// Lookup the object with the name in constant pool entry |name_index|
// dynamically.
void Interpreter::DoLdaLookupSlot(InterpreterAssembler* assembler) {
- DoLoadLookupSlot(Runtime::kLoadLookupSlot, assembler);
+ DoLdaLookupSlot(Runtime::kLoadLookupSlot, assembler);
}
// LdaLookupSlotInsideTypeof <name_index>
@@ -515,11 +538,11 @@
// Lookup the object with the name in constant pool entry |name_index|
// dynamically without causing a NoReferenceError.
void Interpreter::DoLdaLookupSlotInsideTypeof(InterpreterAssembler* assembler) {
- DoLoadLookupSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler);
+ DoLdaLookupSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler);
}
-void Interpreter::DoStoreLookupSlot(LanguageMode language_mode,
- InterpreterAssembler* assembler) {
+void Interpreter::DoStaLookupSlot(LanguageMode language_mode,
+ InterpreterAssembler* assembler) {
Node* value = __ GetAccumulator();
Node* index = __ BytecodeOperandIdx(0);
Node* name = __ LoadConstantPoolEntry(index);
@@ -537,19 +560,19 @@
// Store the object in accumulator to the object with the name in constant
// pool entry |name_index| in sloppy mode.
void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) {
- DoStoreLookupSlot(LanguageMode::SLOPPY, assembler);
+ DoStaLookupSlot(LanguageMode::SLOPPY, assembler);
}
-
// StaLookupSlotStrict <name_index>
//
// Store the object in accumulator to the object with the name in constant
// pool entry |name_index| in strict mode.
void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) {
- DoStoreLookupSlot(LanguageMode::STRICT, assembler);
+ DoStaLookupSlot(LanguageMode::STRICT, assembler);
}
-void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) {
+Node* Interpreter::BuildLoadNamedProperty(Callable ic,
+ InterpreterAssembler* assembler) {
Node* code_target = __ HeapConstant(ic.code());
Node* register_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(register_index);
@@ -559,23 +582,35 @@
Node* smi_slot = __ SmiTag(raw_slot);
Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Node* context = __ GetContext();
- Node* result = __ CallStub(ic.descriptor(), code_target, context, object,
- name, smi_slot, type_feedback_vector);
+ return __ CallStub(ic.descriptor(), code_target, context, object, name,
+ smi_slot, type_feedback_vector);
+}
+
+// LdaNamedProperty <object> <name_index> <slot>
+//
+// Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at
+// constant pool entry <name_index>.
+void Interpreter::DoLdaNamedProperty(InterpreterAssembler* assembler) {
+ Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_);
+ Node* result = BuildLoadNamedProperty(ic, assembler);
__ SetAccumulator(result);
__ Dispatch();
}
-// LoadIC <object> <name_index> <slot>
+// LdrNamedProperty <object> <name_index> <slot> <reg>
//
// Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at
-// constant pool entry <name_index>.
-void Interpreter::DoLoadIC(InterpreterAssembler* assembler) {
- Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
- UNINITIALIZED);
- DoLoadIC(ic, assembler);
+// constant pool entry <name_index> and puts the result into register <reg>.
+void Interpreter::DoLdrNamedProperty(InterpreterAssembler* assembler) {
+ Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_);
+ Node* result = BuildLoadNamedProperty(ic, assembler);
+ Node* destination = __ BytecodeOperandReg(3);
+ __ StoreRegister(result, destination);
+ __ Dispatch();
}
-void Interpreter::DoKeyedLoadIC(Callable ic, InterpreterAssembler* assembler) {
+Node* Interpreter::BuildLoadKeyedProperty(Callable ic,
+ InterpreterAssembler* assembler) {
Node* code_target = __ HeapConstant(ic.code());
Node* reg_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(reg_index);
@@ -584,20 +619,31 @@
Node* smi_slot = __ SmiTag(raw_slot);
Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Node* context = __ GetContext();
- Node* result = __ CallStub(ic.descriptor(), code_target, context, object,
- name, smi_slot, type_feedback_vector);
- __ SetAccumulator(result);
- __ Dispatch();
+ return __ CallStub(ic.descriptor(), code_target, context, object, name,
+ smi_slot, type_feedback_vector);
}
// KeyedLoadIC <object> <slot>
//
// Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key
// in the accumulator.
-void Interpreter::DoKeyedLoadIC(InterpreterAssembler* assembler) {
- Callable ic =
- CodeFactory::KeyedLoadICInOptimizedCode(isolate_, UNINITIALIZED);
- DoKeyedLoadIC(ic, assembler);
+void Interpreter::DoLdaKeyedProperty(InterpreterAssembler* assembler) {
+ Callable ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate_);
+ Node* result = BuildLoadKeyedProperty(ic, assembler);
+ __ SetAccumulator(result);
+ __ Dispatch();
+}
+
+// LdrKeyedProperty <object> <slot> <reg>
+//
+// Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key
+// in the accumulator and puts the result in register <reg>.
+void Interpreter::DoLdrKeyedProperty(InterpreterAssembler* assembler) {
+ Callable ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate_);
+ Node* result = BuildLoadKeyedProperty(ic, assembler);
+ Node* destination = __ BytecodeOperandReg(2);
+ __ StoreRegister(result, destination);
+ __ Dispatch();
}
void Interpreter::DoStoreIC(Callable ic, InterpreterAssembler* assembler) {
@@ -616,27 +662,23 @@
__ Dispatch();
}
-
-// StoreICSloppy <object> <name_index> <slot>
+// StaNamedPropertySloppy <object> <name_index> <slot>
//
// Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and
// the name in constant pool entry <name_index> with the value in the
// accumulator.
-void Interpreter::DoStoreICSloppy(InterpreterAssembler* assembler) {
- Callable ic =
- CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
+void Interpreter::DoStaNamedPropertySloppy(InterpreterAssembler* assembler) {
+ Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY);
DoStoreIC(ic, assembler);
}
-
-// StoreICStrict <object> <name_index> <slot>
+// StaNamedPropertyStrict <object> <name_index> <slot>
//
// Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
// the name in constant pool entry <name_index> with the value in the
// accumulator.
-void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) {
- Callable ic =
- CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
+void Interpreter::DoStaNamedPropertyStrict(InterpreterAssembler* assembler) {
+ Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, STRICT);
DoStoreIC(ic, assembler);
}
@@ -656,25 +698,21 @@
__ Dispatch();
}
-
-// KeyedStoreICSloppy <object> <key> <slot>
+// StaKeyedPropertySloppy <object> <key> <slot>
//
// Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object>
// and the key <key> with the value in the accumulator.
-void Interpreter::DoKeyedStoreICSloppy(InterpreterAssembler* assembler) {
- Callable ic =
- CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
+void Interpreter::DoStaKeyedPropertySloppy(InterpreterAssembler* assembler) {
+ Callable ic = CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY);
DoKeyedStoreIC(ic, assembler);
}
-
-// KeyedStoreICStore <object> <key> <slot>
+// StaKeyedPropertyStrict <object> <key> <slot>
//
// Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
// and the key <key> with the value in the accumulator.
-void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) {
- Callable ic =
- CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
+void Interpreter::DoStaKeyedPropertyStrict(InterpreterAssembler* assembler) {
+ Callable ic = CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT);
DoKeyedStoreIC(ic, assembler);
}
@@ -691,7 +729,6 @@
__ Dispatch();
}
-
// PopContext <context>
//
// Pops the current context and sets <context> as the new context.
@@ -702,33 +739,6 @@
__ Dispatch();
}
-void Interpreter::DoBinaryOp(Callable callable,
- InterpreterAssembler* assembler) {
- // TODO(bmeurer): Collect definition side type feedback for various
- // binary operations.
- Node* target = __ HeapConstant(callable.code());
- Node* reg_index = __ BytecodeOperandReg(0);
- Node* lhs = __ LoadRegister(reg_index);
- Node* rhs = __ GetAccumulator();
- Node* context = __ GetContext();
- Node* result = __ CallStub(callable.descriptor(), target, context, lhs, rhs);
- __ SetAccumulator(result);
- __ Dispatch();
-}
-
-void Interpreter::DoBinaryOp(Runtime::FunctionId function_id,
- InterpreterAssembler* assembler) {
- // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized
- // operations, instead of calling builtins directly.
- Node* reg_index = __ BytecodeOperandReg(0);
- Node* lhs = __ LoadRegister(reg_index);
- Node* rhs = __ GetAccumulator();
- Node* context = __ GetContext();
- Node* result = __ CallRuntime(function_id, context, lhs, rhs);
- __ SetAccumulator(result);
- __ Dispatch();
-}
-
template <class Generator>
void Interpreter::DoBinaryOp(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0);
@@ -747,7 +757,6 @@
DoBinaryOp<AddStub>(assembler);
}
-
// Sub <src>
//
// Subtract register <src> from accumulator.
@@ -755,7 +764,6 @@
DoBinaryOp<SubtractStub>(assembler);
}
-
// Mul <src>
//
// Multiply accumulator by register <src>.
@@ -763,7 +771,6 @@
DoBinaryOp<MultiplyStub>(assembler);
}
-
// Div <src>
//
// Divide register <src> by accumulator.
@@ -771,7 +778,6 @@
DoBinaryOp<DivideStub>(assembler);
}
-
// Mod <src>
//
// Modulo register <src> by accumulator.
@@ -779,7 +785,6 @@
DoBinaryOp<ModulusStub>(assembler);
}
-
// BitwiseOr <src>
//
// BitwiseOr register <src> to accumulator.
@@ -787,7 +792,6 @@
DoBinaryOp<BitwiseOrStub>(assembler);
}
-
// BitwiseXor <src>
//
// BitwiseXor register <src> to accumulator.
@@ -795,7 +799,6 @@
DoBinaryOp<BitwiseXorStub>(assembler);
}
-
// BitwiseAnd <src>
//
// BitwiseAnd register <src> to accumulator.
@@ -803,7 +806,6 @@
DoBinaryOp<BitwiseAndStub>(assembler);
}
-
// ShiftLeft <src>
//
// Left shifts register <src> by the count specified in the accumulator.
@@ -814,7 +816,6 @@
DoBinaryOp<ShiftLeftStub>(assembler);
}
-
// ShiftRight <src>
//
// Right shifts register <src> by the count specified in the accumulator.
@@ -825,7 +826,6 @@
DoBinaryOp<ShiftRightStub>(assembler);
}
-
// ShiftRightLogical <src>
//
// Right Shifts register <src> by the count specified in the accumulator.
@@ -836,6 +836,17 @@
DoBinaryOp<ShiftRightLogicalStub>(assembler);
}
+void Interpreter::DoUnaryOp(Callable callable,
+ InterpreterAssembler* assembler) {
+ Node* target = __ HeapConstant(callable.code());
+ Node* accumulator = __ GetAccumulator();
+ Node* context = __ GetContext();
+ Node* result =
+ __ CallStub(callable.descriptor(), target, context, accumulator);
+ __ SetAccumulator(result);
+ __ Dispatch();
+}
+
template <class Generator>
void Interpreter::DoUnaryOp(InterpreterAssembler* assembler) {
Node* value = __ GetAccumulator();
@@ -845,6 +856,27 @@
__ Dispatch();
}
+// ToName
+//
+// Cast the object referenced by the accumulator to a name.
+void Interpreter::DoToName(InterpreterAssembler* assembler) {
+ DoUnaryOp(CodeFactory::ToName(isolate_), assembler);
+}
+
+// ToNumber
+//
+// Cast the object referenced by the accumulator to a number.
+void Interpreter::DoToNumber(InterpreterAssembler* assembler) {
+ DoUnaryOp(CodeFactory::ToNumber(isolate_), assembler);
+}
+
+// ToObject
+//
+// Cast the object referenced by the accumulator to a JSObject.
+void Interpreter::DoToObject(InterpreterAssembler* assembler) {
+ DoUnaryOp(CodeFactory::ToObject(isolate_), assembler);
+}
+
// Inc
//
// Increments value in the accumulator by one.
@@ -859,14 +891,22 @@
DoUnaryOp<DecStub>(assembler);
}
-void Interpreter::DoLogicalNotOp(Node* value, InterpreterAssembler* assembler) {
+Node* Interpreter::BuildToBoolean(Node* value,
+ InterpreterAssembler* assembler) {
+ Node* context = __ GetContext();
+ return ToBooleanStub::Generate(assembler, value, context);
+}
+
+Node* Interpreter::BuildLogicalNot(Node* value,
+ InterpreterAssembler* assembler) {
+ Variable result(assembler, MachineRepresentation::kTagged);
Label if_true(assembler), if_false(assembler), end(assembler);
Node* true_value = __ BooleanConstant(true);
Node* false_value = __ BooleanConstant(false);
__ BranchIfWordEqual(value, true_value, &if_true, &if_false);
__ Bind(&if_true);
{
- __ SetAccumulator(false_value);
+ result.Bind(false_value);
__ Goto(&end);
}
__ Bind(&if_false);
@@ -875,24 +915,23 @@
__ AbortIfWordNotEqual(value, false_value,
BailoutReason::kExpectedBooleanValue);
}
- __ SetAccumulator(true_value);
+ result.Bind(true_value);
__ Goto(&end);
}
__ Bind(&end);
+ return result.value();
}
-// ToBooleanLogicalNot
+// LogicalNot
//
// Perform logical-not on the accumulator, first casting the
// accumulator to a boolean value if required.
+// ToBooleanLogicalNot
void Interpreter::DoToBooleanLogicalNot(InterpreterAssembler* assembler) {
- Callable callable = CodeFactory::ToBoolean(isolate_);
- Node* target = __ HeapConstant(callable.code());
- Node* accumulator = __ GetAccumulator();
- Node* context = __ GetContext();
- Node* to_boolean_value =
- __ CallStub(callable.descriptor(), target, context, accumulator);
- DoLogicalNotOp(to_boolean_value, assembler);
+ Node* value = __ GetAccumulator();
+ Node* to_boolean_value = BuildToBoolean(value, assembler);
+ Node* result = BuildLogicalNot(to_boolean_value, assembler);
+ __ SetAccumulator(result);
__ Dispatch();
}
@@ -902,7 +941,8 @@
// value.
void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) {
Node* value = __ GetAccumulator();
- DoLogicalNotOp(value, assembler);
+ Node* result = BuildLogicalNot(value, assembler);
+ __ SetAccumulator(result);
__ Dispatch();
}
@@ -911,14 +951,7 @@
// Load the accumulator with the string representating type of the
// object in the accumulator.
void Interpreter::DoTypeOf(InterpreterAssembler* assembler) {
- Callable callable = CodeFactory::Typeof(isolate_);
- Node* target = __ HeapConstant(callable.code());
- Node* accumulator = __ GetAccumulator();
- Node* context = __ GetContext();
- Node* result =
- __ CallStub(callable.descriptor(), target, context, accumulator);
- __ SetAccumulator(result);
- __ Dispatch();
+ DoUnaryOp(CodeFactory::Typeof(isolate_), assembler);
}
void Interpreter::DoDelete(Runtime::FunctionId function_id,
@@ -932,7 +965,6 @@
__ Dispatch();
}
-
// DeletePropertyStrict
//
// Delete the property specified in the accumulator from the object
@@ -941,7 +973,6 @@
DoDelete(Runtime::kDeleteProperty_Strict, assembler);
}
-
// DeletePropertySloppy
//
// Delete the property specified in the accumulator from the object
@@ -967,7 +998,6 @@
__ Dispatch();
}
-
// Call <callable> <receiver> <arg_count>
//
// Call a JSfunction or Callable in |callable| with the |receiver| and
@@ -995,7 +1025,6 @@
__ Dispatch();
}
-
// CallRuntime <function_id> <first_arg> <arg_count>
//
// Call the runtime function |function_id| with the first argument in
@@ -1011,7 +1040,7 @@
// |function_id| with the first argument in |first_arg| and |arg_count|
// arguments in subsequent registers.
void Interpreter::DoInvokeIntrinsic(InterpreterAssembler* assembler) {
- Node* function_id = __ BytecodeOperandRuntimeId(0);
+ Node* function_id = __ BytecodeOperandIntrinsicId(0);
Node* first_arg_reg = __ BytecodeOperandReg(1);
Node* arg_count = __ BytecodeOperandCount(2);
Node* context = __ GetContext();
@@ -1042,7 +1071,6 @@
__ Dispatch();
}
-
// CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return>
//
// Call the runtime function |function_id| which returns a pair, with the
@@ -1074,7 +1102,6 @@
__ Dispatch();
}
-
// CallJSRuntime <context_index> <receiver> <arg_count>
//
// Call the JS runtime function that has the |context_index| with the receiver
@@ -1098,7 +1125,6 @@
__ Dispatch();
}
-
// New <constructor> <first_arg> <arg_count>
//
// Call operator new with |constructor| and the first argument in
@@ -1113,109 +1139,67 @@
//
// Test if the value in the <src> register equals the accumulator.
void Interpreter::DoTestEqual(InterpreterAssembler* assembler) {
- DoBinaryOp(CodeFactory::Equal(isolate_), assembler);
+ DoBinaryOp<EqualStub>(assembler);
}
-
// TestNotEqual <src>
//
// Test if the value in the <src> register is not equal to the accumulator.
void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) {
- DoBinaryOp(CodeFactory::NotEqual(isolate_), assembler);
+ DoBinaryOp<NotEqualStub>(assembler);
}
-
// TestEqualStrict <src>
//
// Test if the value in the <src> register is strictly equal to the accumulator.
void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) {
- DoBinaryOp(CodeFactory::StrictEqual(isolate_), assembler);
+ DoBinaryOp<StrictEqualStub>(assembler);
}
-
// TestLessThan <src>
//
// Test if the value in the <src> register is less than the accumulator.
void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) {
- DoBinaryOp(CodeFactory::LessThan(isolate_), assembler);
+ DoBinaryOp<LessThanStub>(assembler);
}
-
// TestGreaterThan <src>
//
// Test if the value in the <src> register is greater than the accumulator.
void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
- DoBinaryOp(CodeFactory::GreaterThan(isolate_), assembler);
+ DoBinaryOp<GreaterThanStub>(assembler);
}
-
// TestLessThanOrEqual <src>
//
// Test if the value in the <src> register is less than or equal to the
// accumulator.
void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
- DoBinaryOp(CodeFactory::LessThanOrEqual(isolate_), assembler);
+ DoBinaryOp<LessThanOrEqualStub>(assembler);
}
-
// TestGreaterThanOrEqual <src>
//
// Test if the value in the <src> register is greater than or equal to the
// accumulator.
void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) {
- DoBinaryOp(CodeFactory::GreaterThanOrEqual(isolate_), assembler);
+ DoBinaryOp<GreaterThanOrEqualStub>(assembler);
}
-
// TestIn <src>
//
// Test if the object referenced by the register operand is a property of the
// object referenced by the accumulator.
void Interpreter::DoTestIn(InterpreterAssembler* assembler) {
- DoBinaryOp(CodeFactory::HasProperty(isolate_), assembler);
+ DoBinaryOp<HasPropertyStub>(assembler);
}
-
// TestInstanceOf <src>
//
// Test if the object referenced by the <src> register is an an instance of type
// referenced by the accumulator.
void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) {
- DoBinaryOp(CodeFactory::InstanceOf(isolate_), assembler);
-}
-
-void Interpreter::DoTypeConversionOp(Callable callable,
- InterpreterAssembler* assembler) {
- Node* target = __ HeapConstant(callable.code());
- Node* accumulator = __ GetAccumulator();
- Node* context = __ GetContext();
- Node* result =
- __ CallStub(callable.descriptor(), target, context, accumulator);
- __ SetAccumulator(result);
- __ Dispatch();
-}
-
-// ToName
-//
-// Cast the object referenced by the accumulator to a name.
-void Interpreter::DoToName(InterpreterAssembler* assembler) {
- DoTypeConversionOp(CodeFactory::ToName(isolate_), assembler);
-}
-
-
-// ToNumber
-//
-// Cast the object referenced by the accumulator to a number.
-void Interpreter::DoToNumber(InterpreterAssembler* assembler) {
- DoTypeConversionOp(CodeFactory::ToNumber(isolate_), assembler);
-}
-
-
-// ToObject
-//
-// Cast the object referenced by the accumulator to a JSObject.
-void Interpreter::DoToObject(InterpreterAssembler* assembler) {
- DoTypeConversionOp(CodeFactory::ToObject(isolate_), assembler);
+ DoBinaryOp<InstanceOfStub>(assembler);
}
// Jump <imm>
@@ -1289,12 +1273,8 @@
// Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is true when the object is cast to boolean.
void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) {
- Callable callable = CodeFactory::ToBoolean(isolate_);
- Node* target = __ HeapConstant(callable.code());
Node* accumulator = __ GetAccumulator();
- Node* context = __ GetContext();
- Node* to_boolean_value =
- __ CallStub(callable.descriptor(), target, context, accumulator);
+ Node* to_boolean_value = BuildToBoolean(accumulator, assembler);
Node* relative_jump = __ BytecodeOperandImm(0);
Node* true_value = __ BooleanConstant(true);
__ JumpIfWordEqual(to_boolean_value, true_value, relative_jump);
@@ -1307,12 +1287,8 @@
// to boolean.
void Interpreter::DoJumpIfToBooleanTrueConstant(
InterpreterAssembler* assembler) {
- Callable callable = CodeFactory::ToBoolean(isolate_);
- Node* target = __ HeapConstant(callable.code());
Node* accumulator = __ GetAccumulator();
- Node* context = __ GetContext();
- Node* to_boolean_value =
- __ CallStub(callable.descriptor(), target, context, accumulator);
+ Node* to_boolean_value = BuildToBoolean(accumulator, assembler);
Node* index = __ BytecodeOperandIdx(0);
Node* constant = __ LoadConstantPoolEntry(index);
Node* relative_jump = __ SmiUntag(constant);
@@ -1325,12 +1301,8 @@
// Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is false when the object is cast to boolean.
void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) {
- Callable callable = CodeFactory::ToBoolean(isolate_);
- Node* target = __ HeapConstant(callable.code());
Node* accumulator = __ GetAccumulator();
- Node* context = __ GetContext();
- Node* to_boolean_value =
- __ CallStub(callable.descriptor(), target, context, accumulator);
+ Node* to_boolean_value = BuildToBoolean(accumulator, assembler);
Node* relative_jump = __ BytecodeOperandImm(0);
Node* false_value = __ BooleanConstant(false);
__ JumpIfWordEqual(to_boolean_value, false_value, relative_jump);
@@ -1343,12 +1315,8 @@
// to boolean.
void Interpreter::DoJumpIfToBooleanFalseConstant(
InterpreterAssembler* assembler) {
- Callable callable = CodeFactory::ToBoolean(isolate_);
- Node* target = __ HeapConstant(callable.code());
Node* accumulator = __ GetAccumulator();
- Node* context = __ GetContext();
- Node* to_boolean_value =
- __ CallStub(callable.descriptor(), target, context, accumulator);
+ Node* to_boolean_value = BuildToBoolean(accumulator, assembler);
Node* index = __ BytecodeOperandIdx(0);
Node* constant = __ LoadConstantPoolEntry(index);
Node* relative_jump = __ SmiUntag(constant);
@@ -1579,7 +1547,6 @@
}
}
-
// CreateUnmappedArguments
//
// Creates a new unmapped arguments object.
@@ -1639,7 +1606,6 @@
__ Abort(kUnexpectedReturnFromThrow);
}
-
// ReThrow
//
// Re-throws the exception in the accumulator.
@@ -1651,7 +1617,6 @@
__ Abort(kUnexpectedReturnFromThrow);
}
-
// Return
//
// Return the value in the accumulator.
@@ -1821,11 +1786,23 @@
// SuspendGenerator <generator>
//
// Exports the register file and stores it into the generator. Also stores the
-// current context and the state given in the accumulator into the generator.
+// current context, the state given in the accumulator, and the current bytecode
+// offset (for debugging purposes) into the generator.
void Interpreter::DoSuspendGenerator(InterpreterAssembler* assembler) {
Node* generator_reg = __ BytecodeOperandReg(0);
Node* generator = __ LoadRegister(generator_reg);
+ Label if_stepping(assembler, Label::kDeferred), ok(assembler);
+ Node* step_action_address = __ ExternalConstant(
+ ExternalReference::debug_last_step_action_address(isolate_));
+ Node* step_action = __ Load(MachineType::Int8(), step_action_address);
+ STATIC_ASSERT(StepIn > StepNext);
+ STATIC_ASSERT(StepFrame > StepNext);
+ STATIC_ASSERT(LastStepAction == StepFrame);
+ Node* step_next = __ Int32Constant(StepNext);
+ __ BranchIfInt32LessThanOrEqual(step_next, step_action, &if_stepping, &ok);
+ __ Bind(&ok);
+
Node* array =
__ LoadObjectField(generator, JSGeneratorObject::kOperandStackOffset);
Node* context = __ GetContext();
@@ -1835,7 +1812,18 @@
__ StoreObjectField(generator, JSGeneratorObject::kContextOffset, context);
__ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, state);
+ Node* offset = __ SmiTag(__ BytecodeOffset());
+ __ StoreObjectField(generator, JSGeneratorObject::kInputOrDebugPosOffset,
+ offset);
+
__ Dispatch();
+
+ __ Bind(&if_stepping);
+ {
+ Node* context = __ GetContext();
+ __ CallRuntime(Runtime::kDebugRecordAsyncFunction, context, generator);
+ __ Goto(&ok);
+ }
}
// ResumeGenerator <generator>