diff options
author | Michaël Zasso <targos@protonmail.com> | 2017-10-18 15:03:02 -0700 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2017-10-18 17:01:41 -0700 |
commit | 3d1b3df9486c0e7708065257f7311902f6b7b366 (patch) | |
tree | cb051bdeaead11e06dcd97725783e0f113afb1bf /deps/v8/src/frames.cc | |
parent | e2cddbb8ccdb7b3c4a40c8acc630f68703bc77b5 (diff) | |
download | node-new-3d1b3df9486c0e7708065257f7311902f6b7b366.tar.gz |
deps: update V8 to 6.2.414.32
PR-URL: https://github.com/nodejs/node/pull/15362
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/src/frames.cc')
-rw-r--r-- | deps/v8/src/frames.cc | 305 |
1 files changed, 125 insertions, 180 deletions
diff --git a/deps/v8/src/frames.cc b/deps/v8/src/frames.cc index 2b94b2b81f..37f5b4d9cf 100644 --- a/deps/v8/src/frames.cc +++ b/deps/v8/src/frames.cc @@ -10,7 +10,6 @@ #include "src/base/bits.h" #include "src/deoptimizer.h" #include "src/frames-inl.h" -#include "src/full-codegen/full-codegen.h" #include "src/ic/ic-stats.h" #include "src/register-configuration.h" #include "src/safepoint-table.h" @@ -322,7 +321,7 @@ bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const { bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { StackFrame::State state; - if (frame->is_entry() || frame->is_entry_construct()) { + if (frame->is_entry() || frame->is_construct_entry()) { // See EntryFrame::GetCallerState. It computes the caller FP address // and calls ExitFrame::GetStateForFramePointer on it. We need to be // sure that caller FP address is valid. @@ -390,28 +389,18 @@ void SafeStackFrameIterator::Advance() { // ------------------------------------------------------------------------- - -Code* StackFrame::GetSafepointData(Isolate* isolate, - Address inner_pointer, - SafepointEntry* safepoint_entry, - unsigned* stack_slots) { - InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry = - isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer); - if (!entry->safepoint_entry.is_valid()) { - entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer); - DCHECK(entry->safepoint_entry.is_valid()); - } else { - DCHECK(entry->safepoint_entry.Equals( - entry->code->GetSafepointEntry(inner_pointer))); - } - - // Fill in the results and return the code. - Code* code = entry->code; - *safepoint_entry = entry->safepoint_entry; - *stack_slots = code->stack_slots(); - return code; +namespace { +Code* GetContainingCode(Isolate* isolate, Address pc) { + return isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code; } +} // namespace +Code* StackFrame::LookupCode() const { + Code* result = GetContainingCode(isolate(), pc()); + DCHECK_GE(pc(), result->instruction_start()); + DCHECK_LT(pc(), result->instruction_end()); + return result; +} #ifdef DEBUG static bool GcSafeCodeContains(HeapObject* object, Address addr); @@ -500,6 +489,8 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, return JS_TO_WASM; case Code::WASM_INTERPRETER_ENTRY: return WASM_INTERPRETER_ENTRY; + case Code::C_WASM_ENTRY: + return C_WASM_ENTRY; default: // All other types should have an explicit marker break; @@ -513,7 +504,7 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, StackFrame::Type candidate = StackFrame::MarkerToType(marker); switch (candidate) { case ENTRY: - case ENTRY_CONSTRUCT: + case CONSTRUCT_ENTRY: case EXIT: case BUILTIN_CONTINUATION: case JAVA_SCRIPT_BUILTIN_CONTINUATION: @@ -567,20 +558,13 @@ void EntryFrame::ComputeCallerState(State* state) const { } -void EntryFrame::SetCallerFp(Address caller_fp) { - const int offset = EntryFrameConstants::kCallerFPOffset; - Memory::Address_at(this->fp() + offset) = caller_fp; -} - - StackFrame::Type EntryFrame::GetCallerState(State* state) const { const int offset = EntryFrameConstants::kCallerFPOffset; Address fp = Memory::Address_at(this->fp() + offset); return ExitFrame::GetStateForFramePointer(fp, state); } - -Code* EntryConstructFrame::unchecked_code() const { +Code* ConstructEntryFrame::unchecked_code() const { return isolate()->heap()->js_construct_entry_code(); } @@ -609,10 +593,6 @@ void ExitFrame::ComputeCallerState(State* state) const { } -void ExitFrame::SetCallerFp(Address caller_fp) { - Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; -} - void ExitFrame::Iterate(RootVisitor* v) const { // The arguments are traversed as part of the expression stack of // the calling frame. @@ -699,6 +679,13 @@ int BuiltinExitFrame::ComputeParametersCount() const { return argc; } +namespace { +void PrintIndex(StringStream* accumulator, StackFrame::PrintMode mode, + int index) { + accumulator->Add((mode == StackFrame::OVERVIEW) ? "%5d: " : "[%d]: ", index); +} +} // namespace + void BuiltinExitFrame::Print(StringStream* accumulator, PrintMode mode, int index) const { DisallowHeapAllocation no_gc; @@ -779,14 +766,9 @@ void StandardFrame::ComputeCallerState(State* state) const { } -void StandardFrame::SetCallerFp(Address caller_fp) { - Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) = - caller_fp; -} - bool StandardFrame::IsConstructor() const { return false; } -void StandardFrame::Summarize(List<FrameSummary>* functions, +void StandardFrame::Summarize(std::vector<FrameSummary>* functions, FrameSummary::Mode mode) const { // This should only be called on frames which override this method. UNREACHABLE(); @@ -797,11 +779,21 @@ void StandardFrame::IterateCompiledFrame(RootVisitor* v) const { // possibly find pointers in optimized frames in that state. DCHECK(can_access_heap_objects()); - // Compute the safepoint information. - unsigned stack_slots = 0; - SafepointEntry safepoint_entry; - Code* code = StackFrame::GetSafepointData( - isolate(), pc(), &safepoint_entry, &stack_slots); + // Find the code and compute the safepoint information. + Address inner_pointer = pc(); + InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry = + isolate()->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer); + if (!entry->safepoint_entry.is_valid()) { + entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer); + DCHECK(entry->safepoint_entry.is_valid()); + } else { + DCHECK(entry->safepoint_entry.Equals( + entry->code->GetSafepointEntry(inner_pointer))); + } + + Code* code = entry->code; + SafepointEntry safepoint_entry = entry->safepoint_entry; + unsigned stack_slots = code->stack_slots(); unsigned slot_space = stack_slots * kPointerSize; // Determine the fixed header and spill slot area size. @@ -812,7 +804,7 @@ void StandardFrame::IterateCompiledFrame(RootVisitor* v) const { StackFrame::Type candidate = StackFrame::MarkerToType(marker); switch (candidate) { case ENTRY: - case ENTRY_CONSTRUCT: + case CONSTRUCT_ENTRY: case EXIT: case BUILTIN_CONTINUATION: case JAVA_SCRIPT_BUILTIN_CONTINUATION: @@ -825,6 +817,7 @@ void StandardFrame::IterateCompiledFrame(RootVisitor* v) const { case WASM_TO_JS: case WASM_COMPILED: case WASM_INTERPRETER_ENTRY: + case C_WASM_ENTRY: frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp; break; case JAVA_SCRIPT: @@ -862,9 +855,9 @@ void StandardFrame::IterateCompiledFrame(RootVisitor* v) const { if (safepoint_entry.has_doubles()) { // Number of doubles not known at snapshot time. DCHECK(!isolate()->serializer_enabled()); - parameters_base += RegisterConfiguration::Crankshaft() - ->num_allocatable_double_registers() * - kDoubleSize / kPointerSize; + parameters_base += + RegisterConfiguration::Default()->num_allocatable_double_registers() * + kDoubleSize / kPointerSize; } // Visit the registers that contain pointers if any. @@ -951,9 +944,9 @@ bool JavaScriptFrame::IsConstructor() const { bool JavaScriptFrame::HasInlinedFrames() const { - List<SharedFunctionInfo*> functions(1); + std::vector<SharedFunctionInfo*> functions; GetFunctions(&functions); - return functions.length() > 1; + return functions.size() > 1; } @@ -984,31 +977,32 @@ Address JavaScriptFrame::GetCallerStackPointer() const { return fp() + StandardFrameConstants::kCallerSPOffset; } -void JavaScriptFrame::GetFunctions(List<SharedFunctionInfo*>* functions) const { - DCHECK(functions->length() == 0); - functions->Add(function()->shared()); +void JavaScriptFrame::GetFunctions( + std::vector<SharedFunctionInfo*>* functions) const { + DCHECK(functions->empty()); + functions->push_back(function()->shared()); } void JavaScriptFrame::GetFunctions( - List<Handle<SharedFunctionInfo>>* functions) const { - DCHECK(functions->length() == 0); - List<SharedFunctionInfo*> raw_functions; + std::vector<Handle<SharedFunctionInfo>>* functions) const { + DCHECK(functions->empty()); + std::vector<SharedFunctionInfo*> raw_functions; GetFunctions(&raw_functions); for (const auto& raw_function : raw_functions) { - functions->Add(Handle<SharedFunctionInfo>(raw_function)); + functions->push_back(Handle<SharedFunctionInfo>(raw_function)); } } -void JavaScriptFrame::Summarize(List<FrameSummary>* functions, +void JavaScriptFrame::Summarize(std::vector<FrameSummary>* functions, FrameSummary::Mode mode) const { - DCHECK(functions->length() == 0); + DCHECK(functions->empty()); Code* code = LookupCode(); int offset = static_cast<int>(pc() - code->instruction_start()); AbstractCode* abstract_code = AbstractCode::cast(code); FrameSummary::JavaScriptFrameSummary summary(isolate(), receiver(), function(), abstract_code, offset, IsConstructor(), mode); - functions->Add(summary); + functions->push_back(summary); } JSFunction* JavaScriptFrame::function() const { @@ -1305,10 +1299,11 @@ FrameSummary::~FrameSummary() { } FrameSummary FrameSummary::GetTop(const StandardFrame* frame) { - List<FrameSummary> frames(FLAG_max_inlining_levels + 1); + std::vector<FrameSummary> frames; + frames.reserve(FLAG_max_inlining_levels + 1); frame->Summarize(&frames); - DCHECK_LT(0, frames.length()); - return frames.last(); + DCHECK_LT(0, frames.size()); + return frames.back(); } FrameSummary FrameSummary::GetBottom(const StandardFrame* frame) { @@ -1316,17 +1311,18 @@ FrameSummary FrameSummary::GetBottom(const StandardFrame* frame) { } FrameSummary FrameSummary::GetSingle(const StandardFrame* frame) { - List<FrameSummary> frames(1); + std::vector<FrameSummary> frames; frame->Summarize(&frames); - DCHECK_EQ(1, frames.length()); - return frames.first(); + DCHECK_EQ(1, frames.size()); + return frames.front(); } FrameSummary FrameSummary::Get(const StandardFrame* frame, int index) { DCHECK_LE(0, index); - List<FrameSummary> frames(FLAG_max_inlining_levels + 1); + std::vector<FrameSummary> frames; + frames.reserve(FLAG_max_inlining_levels + 1); frame->Summarize(&frames); - DCHECK_GT(frames.length(), index); + DCHECK_GT(frames.size(), index); return frames[index]; } @@ -1357,9 +1353,9 @@ FRAME_SUMMARY_DISPATCH(Handle<Context>, native_context) #undef FRAME_SUMMARY_DISPATCH -void OptimizedFrame::Summarize(List<FrameSummary>* frames, +void OptimizedFrame::Summarize(std::vector<FrameSummary>* frames, FrameSummary::Mode mode) const { - DCHECK(frames->length() == 0); + DCHECK(frames->empty()); DCHECK(is_optimized()); // Delegate to JS frame in absence of turbofan deoptimization. @@ -1370,101 +1366,71 @@ void OptimizedFrame::Summarize(List<FrameSummary>* frames, return JavaScriptFrame::Summarize(frames); } - DisallowHeapAllocation no_gc; int deopt_index = Safepoint::kNoDeoptimizationIndex; DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index); if (deopt_index == Safepoint::kNoDeoptimizationIndex) { - DCHECK(data == nullptr); + CHECK_NULL(data); 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(), - data->TranslationIndex(deopt_index)->value()); - Translation::Opcode frame_opcode = - static_cast<Translation::Opcode>(it.Next()); - DCHECK_EQ(Translation::BEGIN, frame_opcode); - it.Next(); // Drop frame count. - int jsframe_count = it.Next(); + // Prepare iteration over translation. Note that the below iteration might + // materialize objects without storing them back to the Isolate, this will + // lead to objects being re-materialized again for each summary. + TranslatedState translated(this); + translated.Prepare(fp()); // We create the summary in reverse order because the frames // in the deoptimization translation are ordered bottom-to-top. bool is_constructor = IsConstructor(); - while (jsframe_count != 0) { - frame_opcode = static_cast<Translation::Opcode>(it.Next()); - if (frame_opcode == Translation::INTERPRETED_FRAME || - frame_opcode == Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME) { - jsframe_count--; - BailoutId const bailout_id = BailoutId(it.Next()); - SharedFunctionInfo* const shared_info = - SharedFunctionInfo::cast(literal_array->get(it.Next())); - it.Next(); // Skip height. + for (auto it = translated.begin(); it != translated.end(); it++) { + if (it->kind() == TranslatedFrame::kInterpretedFunction || + it->kind() == TranslatedFrame::kJavaScriptBuiltinContinuation) { + Handle<SharedFunctionInfo> shared_info = it->shared_info(); // The translation commands are ordered and the function is always // at the first position, and the receiver is next. - Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); + TranslatedFrame::iterator translated_values = it->begin(); - // Get the correct function in the optimized frame. - JSFunction* function; - if (opcode == Translation::LITERAL) { - function = JSFunction::cast(literal_array->get(it.Next())); - } else { - CHECK_EQ(opcode, Translation::STACK_SLOT); - function = JSFunction::cast(StackSlotAt(it.Next())); - } - DCHECK_EQ(shared_info, function->shared()); - - // If we are at a call, the receiver is always in a stack slot. - // Otherwise we are not guaranteed to get the receiver value. - opcode = static_cast<Translation::Opcode>(it.Next()); - - // Get the correct receiver in the optimized frame. - Object* receiver; - if (opcode == Translation::LITERAL) { - receiver = literal_array->get(it.Next()); - } else if (opcode == Translation::STACK_SLOT) { - receiver = StackSlotAt(it.Next()); - } else { - // The receiver is not in a stack slot nor in a literal. We give up. - it.Skip(Translation::NumberOfOperandsFor(opcode)); - // TODO(3029): Materializing a captured object (or duplicated - // object) is hard, we return undefined for now. This breaks the - // produced stack trace, as constructor frames aren't marked as - // such anymore. - receiver = isolate()->heap()->undefined_value(); - } + // Get or materialize the correct function in the optimized frame. + Handle<JSFunction> function = + Handle<JSFunction>::cast(translated_values->GetValue()); + translated_values++; - AbstractCode* abstract_code; + // Get or materialize the correct receiver in the optimized frame. + Handle<Object> receiver = translated_values->GetValue(); + translated_values++; + // Determine the underlying code object and the position within it from + // the translation corresponding to the frame type in question. + Handle<AbstractCode> abstract_code; unsigned code_offset; - if (frame_opcode == Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME) { + if (it->kind() == TranslatedFrame::kJavaScriptBuiltinContinuation) { code_offset = 0; - abstract_code = AbstractCode::cast(isolate()->builtins()->builtin( - Builtins::GetBuiltinFromBailoutId(bailout_id))); + abstract_code = + handle(AbstractCode::cast(isolate()->builtins()->builtin( + Builtins::GetBuiltinFromBailoutId(it->node_id()))), + isolate()); } else { - DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME); - code_offset = bailout_id.ToInt(); // Points to current bytecode. - abstract_code = AbstractCode::cast(shared_info->bytecode_array()); + DCHECK_EQ(it->kind(), TranslatedFrame::kInterpretedFunction); + code_offset = it->node_id().ToInt(); // Points to current bytecode. + abstract_code = handle(shared_info->abstract_code(), isolate()); } - FrameSummary::JavaScriptFrameSummary summary(isolate(), receiver, - function, abstract_code, + + // Append full summary of the encountered JS frame. + FrameSummary::JavaScriptFrameSummary summary(isolate(), *receiver, + *function, *abstract_code, code_offset, is_constructor); - frames->Add(summary); + frames->push_back(summary); is_constructor = false; - } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) { - // The next encountered JS_FRAME will be marked as a constructor call. - it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); + } else if (it->kind() == TranslatedFrame::kConstructStub) { + // The next encountered JS frame will be marked as a constructor call. DCHECK(!is_constructor); is_constructor = true; - } else { - // Skip over operands to advance to the next opcode. - it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); } } - DCHECK(!is_constructor); } @@ -1478,6 +1444,15 @@ int OptimizedFrame::LookupExceptionHandlerInTable( HandlerTable* table = HandlerTable::cast(code->handler_table()); int pc_offset = static_cast<int>(pc() - code->entry()); if (stack_slots) *stack_slots = code->stack_slots(); + + // When the return pc has been replaced by a trampoline there won't be + // a handler for this trampoline. Thus we need to use the return pc that + // _used to be_ on the stack to get the right ExceptionHandler. + if (code->kind() == Code::OPTIMIZED_FUNCTION && + code->marked_for_deoptimization()) { + SafepointTable safepoints(code); + pc_offset = safepoints.find_return_pc(pc_offset); + } return table->LookupReturn(pc_offset); } @@ -1521,8 +1496,9 @@ Object* OptimizedFrame::receiver() const { } } -void OptimizedFrame::GetFunctions(List<SharedFunctionInfo*>* functions) const { - DCHECK(functions->length() == 0); +void OptimizedFrame::GetFunctions( + std::vector<SharedFunctionInfo*>* functions) const { + DCHECK(functions->empty()); DCHECK(is_optimized()); // Delegate to JS frame in absence of turbofan deoptimization. @@ -1558,7 +1534,7 @@ void OptimizedFrame::GetFunctions(List<SharedFunctionInfo*>* functions) const { // The second operand of the frame points to the function. Object* shared = literal_array->get(it.Next()); - functions->Add(SharedFunctionInfo::cast(shared)); + functions->push_back(SharedFunctionInfo::cast(shared)); // Skip over remaining operands to advance to the next opcode. it.Skip(Translation::NumberOfOperandsFor(opcode) - 2); @@ -1655,15 +1631,15 @@ void InterpretedFrame::WriteInterpreterRegister(int register_index, return SetExpression(index + register_index, value); } -void InterpretedFrame::Summarize(List<FrameSummary>* functions, +void InterpretedFrame::Summarize(std::vector<FrameSummary>* functions, FrameSummary::Mode mode) const { - DCHECK(functions->length() == 0); + DCHECK(functions->empty()); AbstractCode* abstract_code = AbstractCode::cast(function()->shared()->bytecode_array()); FrameSummary::JavaScriptFrameSummary summary( isolate(), receiver(), function(), abstract_code, GetBytecodeOffset(), IsConstructor()); - functions->Add(summary); + functions->push_back(summary); } int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { @@ -1702,12 +1678,6 @@ Code* InternalFrame::unchecked_code() const { } -void StackFrame::PrintIndex(StringStream* accumulator, - PrintMode mode, - int index) { - accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); -} - void WasmCompiledFrame::Print(StringStream* accumulator, PrintMode mode, int index) const { PrintIndex(accumulator, mode, index); @@ -1760,15 +1730,15 @@ int WasmCompiledFrame::position() const { return FrameSummary::GetSingle(this).SourcePosition(); } -void WasmCompiledFrame::Summarize(List<FrameSummary>* functions, +void WasmCompiledFrame::Summarize(std::vector<FrameSummary>* functions, FrameSummary::Mode mode) const { - DCHECK_EQ(0, functions->length()); + DCHECK(functions->empty()); Handle<Code> code(LookupCode(), isolate()); int offset = static_cast<int>(pc() - code->instruction_start()); Handle<WasmInstanceObject> instance(wasm_instance(), isolate()); FrameSummary::WasmCompiledFrameSummary summary( isolate(), instance, code, offset, at_to_number_conversion()); - functions->Add(summary); + functions->push_back(summary); } bool WasmCompiledFrame::at_to_number_conversion() const { @@ -1807,7 +1777,7 @@ void WasmInterpreterEntryFrame::Print(StringStream* accumulator, PrintMode mode, if (mode != OVERVIEW) accumulator->Add("\n"); } -void WasmInterpreterEntryFrame::Summarize(List<FrameSummary>* functions, +void WasmInterpreterEntryFrame::Summarize(std::vector<FrameSummary>* functions, FrameSummary::Mode mode) const { Handle<WasmInstanceObject> instance(wasm_instance(), isolate()); std::vector<std::pair<uint32_t, int>> interpreted_stack = @@ -1816,7 +1786,7 @@ void WasmInterpreterEntryFrame::Summarize(List<FrameSummary>* functions, for (auto& e : interpreted_stack) { FrameSummary::WasmInterpretedFrameSummary summary(isolate(), instance, e.first, e.second); - functions->Add(summary); + functions->push_back(summary); } } @@ -2184,31 +2154,6 @@ InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* // ------------------------------------------------------------------------- -int NumRegs(RegList reglist) { return base::bits::CountPopulation(reglist); } - - -struct JSCallerSavedCodeData { - int reg_code[kNumJSCallerSaved]; -}; - -JSCallerSavedCodeData caller_saved_code_data; - -void SetUpJSCallerSavedCodeData() { - int i = 0; - for (int r = 0; r < kNumRegs; r++) - if ((kJSCallerSaved & (1 << r)) != 0) - caller_saved_code_data.reg_code[i++] = r; - - DCHECK(i == kNumJSCallerSaved); -} - - -int JSCallerSavedCode(int n) { - DCHECK(0 <= n && n < kNumJSCallerSaved); - return caller_saved_code_data.reg_code[n]; -} - - #define DEFINE_WRAPPER(type, field) \ class field##_Wrapper : public ZoneObject { \ public: /* NOLINT */ \ |