Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/frames.cc b/src/frames.cc
index 0e57429..a8fe6bb 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -16,6 +16,7 @@
#include "src/safepoint-table.h"
#include "src/string-stream.h"
#include "src/vm-state-inl.h"
+#include "src/wasm/wasm-module.h"
namespace v8 {
namespace internal {
@@ -104,17 +105,15 @@
StackFrame::Type type = ExitFrame::GetStateForFramePointer(
Isolate::c_entry_fp(top), &state);
handler_ = StackHandler::FromAddress(Isolate::handler(top));
- if (SingletonFor(type) == NULL) return;
frame_ = SingletonFor(type, &state);
}
StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
StackFrame::State* state) {
- if (type == StackFrame::NONE) return NULL;
StackFrame* result = SingletonFor(type);
- DCHECK(result != NULL);
- result->state_ = *state;
+ DCHECK((!result) == (type == StackFrame::NONE));
+ if (result) result->state_ = *state;
return result;
}
@@ -162,28 +161,29 @@
// -------------------------------------------------------------------------
-
StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
- : JavaScriptFrameIterator(isolate) {
- if (!done() && !IsValidFrame()) Advance();
+ : iterator_(isolate) {
+ if (!done() && !IsValidFrame(iterator_.frame())) Advance();
}
void StackTraceFrameIterator::Advance() {
- while (true) {
- JavaScriptFrameIterator::Advance();
- if (done()) return;
- if (IsValidFrame()) return;
- }
+ do {
+ iterator_.Advance();
+ } while (!done() && !IsValidFrame(iterator_.frame()));
}
-
-bool StackTraceFrameIterator::IsValidFrame() {
- if (!frame()->function()->IsJSFunction()) return false;
- Object* script = frame()->function()->shared()->script();
+bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const {
+ if (frame->is_java_script()) {
+ JavaScriptFrame* jsFrame = static_cast<JavaScriptFrame*>(frame);
+ if (!jsFrame->function()->IsJSFunction()) return false;
+ Object* script = jsFrame->function()->shared()->script();
// Don't show functions from native scripts to user.
return (script->IsScript() &&
Script::TYPE_NATIVE != Script::cast(script)->type());
+ }
+ // apart from javascript, only wasm is valid
+ return frame->is_wasm();
}
@@ -230,10 +230,8 @@
} else {
return;
}
- if (SingletonFor(type) == NULL) return;
frame_ = SingletonFor(type, &state);
- DCHECK(frame_);
- Advance();
+ if (frame_) Advance();
}
@@ -261,12 +259,8 @@
// Advance to the previous frame.
StackFrame::State state;
StackFrame::Type type = frame_->GetCallerState(&state);
- if (SingletonFor(type) == NULL) {
- frame_ = NULL;
- return;
- }
frame_ = SingletonFor(type, &state);
- DCHECK(frame_);
+ if (!frame_) return;
// Check that we have actually moved to the previous frame in the stack.
if (frame_->sp() < last_sp || frame_->fp() < last_fp) {
@@ -493,10 +487,10 @@
case INTERNAL:
case CONSTRUCT:
case ARGUMENTS_ADAPTOR:
- return candidate;
- case JS_TO_WASM:
case WASM_TO_JS:
case WASM:
+ return candidate;
+ case JS_TO_WASM:
case JAVA_SCRIPT:
case OPTIMIZED:
case INTERPRETED:
@@ -624,7 +618,6 @@
state->constant_pool_address = NULL;
}
-
Address StandardFrame::GetExpressionAddress(int n) const {
const int offset = StandardFrameConstants::kExpressionsOffset;
return fp() + offset - n * kPointerSize;
@@ -711,7 +704,8 @@
(frame_header_size + StandardFrameConstants::kFixedFrameSizeAboveFp);
Object** frame_header_base = &Memory::Object_at(fp() - frame_header_size);
- Object** frame_header_limit = &Memory::Object_at(fp());
+ Object** frame_header_limit =
+ &Memory::Object_at(fp() - StandardFrameConstants::kCPSlotSize);
Object** parameters_base = &Memory::Object_at(sp());
Object** parameters_limit = frame_header_base - slot_space / kPointerSize;
@@ -854,17 +848,23 @@
functions->Add(function());
}
-
-void JavaScriptFrame::Summarize(List<FrameSummary>* functions) {
+void JavaScriptFrame::Summarize(List<FrameSummary>* functions,
+ FrameSummary::Mode mode) const {
DCHECK(functions->length() == 0);
Code* code = LookupCode();
int offset = static_cast<int>(pc() - code->instruction_start());
AbstractCode* abstract_code = AbstractCode::cast(code);
FrameSummary summary(receiver(), function(), abstract_code, offset,
- IsConstructor());
+ IsConstructor(), mode);
functions->Add(summary);
}
+JSFunction* JavaScriptFrame::function() const {
+ return JSFunction::cast(function_slot_object());
+}
+
+Object* JavaScriptFrame::receiver() const { return GetParameter(-1); }
+
int JavaScriptFrame::LookupExceptionHandlerInTable(
int* stack_depth, HandlerTable::CatchPrediction* prediction) {
Code* code = LookupCode();
@@ -944,16 +944,6 @@
}
}
-
-void JavaScriptFrame::RestoreOperandStack(FixedArray* store) {
- int operands_count = store->length();
- DCHECK_LE(operands_count, ComputeOperandsCount());
- for (int i = 0; i < operands_count; i++) {
- DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
- Memory::Object_at(GetOperandSlot(i)) = store->get(i);
- }
-}
-
namespace {
bool CannotDeoptFromAsmCode(Code* code, JSFunction* function) {
@@ -965,7 +955,7 @@
FrameSummary::FrameSummary(Object* receiver, JSFunction* function,
AbstractCode* abstract_code, int code_offset,
- bool is_constructor)
+ bool is_constructor, Mode mode)
: receiver_(receiver, function->GetIsolate()),
function_(function),
abstract_code_(abstract_code),
@@ -973,7 +963,14 @@
is_constructor_(is_constructor) {
DCHECK(abstract_code->IsBytecodeArray() ||
Code::cast(abstract_code)->kind() != Code::OPTIMIZED_FUNCTION ||
- CannotDeoptFromAsmCode(Code::cast(abstract_code), function));
+ CannotDeoptFromAsmCode(Code::cast(abstract_code), function) ||
+ mode == kApproximateSummary);
+}
+
+FrameSummary FrameSummary::GetFirst(JavaScriptFrame* frame) {
+ List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
+ frame->Summarize(&frames);
+ return frames.first();
}
void FrameSummary::Print() {
@@ -987,8 +984,12 @@
Code* code = abstract_code_->GetCode();
if (code->kind() == Code::FUNCTION) PrintF(" UNOPT ");
if (code->kind() == Code::OPTIMIZED_FUNCTION) {
- DCHECK(CannotDeoptFromAsmCode(code, *function()));
- PrintF(" ASM ");
+ if (function()->shared()->asm_function()) {
+ DCHECK(CannotDeoptFromAsmCode(code, *function()));
+ PrintF(" ASM ");
+ } else {
+ PrintF(" OPT (approximate)");
+ }
}
} else {
PrintF(" BYTECODE ");
@@ -996,8 +997,8 @@
PrintF("\npc: %d\n", code_offset_);
}
-
-void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
+void OptimizedFrame::Summarize(List<FrameSummary>* frames,
+ FrameSummary::Mode mode) const {
DCHECK(frames->length() == 0);
DCHECK(is_optimized());
@@ -1012,6 +1013,13 @@
DisallowHeapAllocation no_gc;
int deopt_index = Safepoint::kNoDeoptimizationIndex;
DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index);
+ if (deopt_index == Safepoint::kNoDeoptimizationIndex) {
+ DCHECK(data == nullptr);
+ if (mode == FrameSummary::kApproximateSummary) {
+ return JavaScriptFrame::Summarize(frames, mode);
+ }
+ FATAL("Missing deoptimization information for OptimizedFrame::Summarize.");
+ }
FixedArray* const literal_array = data->LiteralArray();
TranslationIterator it(data->TranslationByteArray(),
@@ -1134,9 +1142,10 @@
SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
*deopt_index = safepoint_entry.deoptimization_index();
- DCHECK(*deopt_index != Safepoint::kNoDeoptimizationIndex);
-
- return DeoptimizationInputData::cast(code->deoptimization_data());
+ if (*deopt_index != Safepoint::kNoDeoptimizationIndex) {
+ return DeoptimizationInputData::cast(code->deoptimization_data());
+ }
+ return nullptr;
}
@@ -1155,6 +1164,8 @@
DisallowHeapAllocation no_gc;
int deopt_index = Safepoint::kNoDeoptimizationIndex;
DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index);
+ DCHECK_NOT_NULL(data);
+ DCHECK_NE(Safepoint::kNoDeoptimizationIndex, deopt_index);
FixedArray* const literal_array = data->LiteralArray();
TranslationIterator it(data->TranslationByteArray(),
@@ -1228,15 +1239,15 @@
SetExpression(index, Smi::FromInt(raw_offset));
}
-Object* InterpretedFrame::GetBytecodeArray() const {
+BytecodeArray* InterpretedFrame::GetBytecodeArray() const {
const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
DCHECK_EQ(
InterpreterFrameConstants::kBytecodeArrayFromFp,
InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
- return GetExpression(index);
+ return BytecodeArray::cast(GetExpression(index));
}
-void InterpretedFrame::PatchBytecodeArray(Object* bytecode_array) {
+void InterpretedFrame::PatchBytecodeArray(BytecodeArray* bytecode_array) {
const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
DCHECK_EQ(
InterpreterFrameConstants::kBytecodeArrayFromFp,
@@ -1244,15 +1255,25 @@
SetExpression(index, bytecode_array);
}
-Object* InterpretedFrame::GetInterpreterRegister(int register_index) const {
+Object* InterpretedFrame::ReadInterpreterRegister(int register_index) const {
const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
DCHECK_EQ(
- InterpreterFrameConstants::kRegisterFilePointerFromFp,
+ InterpreterFrameConstants::kRegisterFileFromFp,
InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
return GetExpression(index + register_index);
}
-void InterpretedFrame::Summarize(List<FrameSummary>* functions) {
+void InterpretedFrame::WriteInterpreterRegister(int register_index,
+ Object* value) {
+ const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
+ DCHECK_EQ(
+ InterpreterFrameConstants::kRegisterFileFromFp,
+ InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
+ return SetExpression(index + register_index, value);
+}
+
+void InterpretedFrame::Summarize(List<FrameSummary>* functions,
+ FrameSummary::Mode mode) const {
DCHECK(functions->length() == 0);
AbstractCode* abstract_code =
AbstractCode::cast(function()->shared()->bytecode_array());
@@ -1315,6 +1336,32 @@
return fp() + ExitFrameConstants::kCallerSPOffset;
}
+Object* WasmFrame::wasm_obj() {
+ FixedArray* deopt_data = LookupCode()->deoptimization_data();
+ DCHECK(deopt_data->length() == 2);
+ return deopt_data->get(0);
+}
+
+uint32_t WasmFrame::function_index() {
+ FixedArray* deopt_data = LookupCode()->deoptimization_data();
+ DCHECK(deopt_data->length() == 2);
+ Object* func_index_obj = deopt_data->get(1);
+ if (func_index_obj->IsUndefined()) return static_cast<uint32_t>(-1);
+ if (func_index_obj->IsSmi()) return Smi::cast(func_index_obj)->value();
+ DCHECK(func_index_obj->IsHeapNumber());
+ uint32_t val = static_cast<uint32_t>(-1);
+ func_index_obj->ToUint32(&val);
+ DCHECK(val != static_cast<uint32_t>(-1));
+ return val;
+}
+
+Object* WasmFrame::function_name() {
+ Object* wasm_object = wasm_obj();
+ if (wasm_object->IsUndefined()) return wasm_object;
+ Handle<JSObject> wasm = handle(JSObject::cast(wasm_object));
+ return *wasm::GetWasmFunctionName(wasm, function_index());
+}
+
namespace {
@@ -1364,14 +1411,20 @@
int offset = static_cast<int>(pc - code->instruction_start());
int source_pos = code->SourcePosition(offset);
int line = script->GetLineNumber(source_pos) + 1;
- accumulator->Add(":%d", line);
+ accumulator->Add(":%d] [pc=%p]", line, pc);
+ } else if (is_interpreted()) {
+ const InterpretedFrame* iframe =
+ reinterpret_cast<const InterpretedFrame*>(this);
+ BytecodeArray* bytecodes = iframe->GetBytecodeArray();
+ int offset = iframe->GetBytecodeOffset();
+ int source_pos = bytecodes->SourcePosition(offset);
+ int line = script->GetLineNumber(source_pos) + 1;
+ accumulator->Add(":%d] [bytecode=%p offset=%d]", line, bytecodes, offset);
} else {
int function_start_pos = shared->start_position();
int line = script->GetLineNumber(function_start_pos) + 1;
- accumulator->Add(":~%d", line);
+ accumulator->Add(":~%d] [pc=%p]", line, pc);
}
-
- accumulator->Add("] [pc=%p] ", pc);
}
accumulator->Add("(this=%o", receiver);
@@ -1632,7 +1685,8 @@
Page* page = Page::FromAddress(inner_pointer);
DCHECK_EQ(page->owner(), heap->code_space());
- heap->mark_compact_collector()->SweepOrWaitUntilSweepingCompleted(page);
+ heap->mark_compact_collector()->sweeper().SweepOrWaitUntilSweepingCompleted(
+ page);
Address addr = page->skip_list()->StartFor(inner_pointer);