summaryrefslogtreecommitdiff
path: root/deps/v8/src/codegen/compiler.cc
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2019-08-16 11:32:46 +0200
committerMichaël Zasso <targos@protonmail.com>2019-08-19 09:25:23 +0200
commite31f0a7d25668d3c1531294d2ef44a9f3bde4ef4 (patch)
tree6c6bed9804be9df6162b2483f0a56f371f66464d /deps/v8/src/codegen/compiler.cc
parentec16fdae540adaf710b1a86c620170b2880088f0 (diff)
downloadandroid-node-v8-e31f0a7d25668d3c1531294d2ef44a9f3bde4ef4.tar.gz
android-node-v8-e31f0a7d25668d3c1531294d2ef44a9f3bde4ef4.tar.bz2
android-node-v8-e31f0a7d25668d3c1531294d2ef44a9f3bde4ef4.zip
deps: update V8 to 7.7.299.4
PR-URL: https://github.com/nodejs/node/pull/28918 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'deps/v8/src/codegen/compiler.cc')
-rw-r--r--deps/v8/src/codegen/compiler.cc155
1 files changed, 122 insertions, 33 deletions
diff --git a/deps/v8/src/codegen/compiler.cc b/deps/v8/src/codegen/compiler.cc
index 5197dd3a2f..906eb0f0ca 100644
--- a/deps/v8/src/codegen/compiler.cc
+++ b/deps/v8/src/codegen/compiler.cc
@@ -15,8 +15,10 @@
#include "src/codegen/assembler-inl.h"
#include "src/codegen/compilation-cache.h"
#include "src/codegen/optimized-compilation-info.h"
+#include "src/codegen/pending-optimization-table.h"
#include "src/codegen/unoptimized-compilation-info.h"
#include "src/common/globals.h"
+#include "src/common/message-template.h"
#include "src/compiler-dispatcher/compiler-dispatcher.h"
#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
#include "src/compiler/pipeline.h"
@@ -24,7 +26,6 @@
#include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h"
#include "src/execution/isolate-inl.h"
-#include "src/execution/message-template.h"
#include "src/execution/runtime-profiler.h"
#include "src/execution/vm-state-inl.h"
#include "src/heap/heap-inl.h"
@@ -319,6 +320,8 @@ void OptimizedCompilationJob::RecordCompilationStats(CompilationMode mode,
counters->turbofan_optimize_total_foreground()->AddSample(
static_cast<int>(time_foreground.InMicroseconds()));
}
+ counters->turbofan_ticks()->AddSample(static_cast<int>(
+ compilation_info()->tick_counter().CurrentTicks() / 1000));
}
}
@@ -593,6 +596,12 @@ MaybeHandle<SharedFunctionInfo> GenerateUnoptimizedCodeForToplevel(
return MaybeHandle<SharedFunctionInfo>();
}
+ if (FLAG_stress_lazy_source_positions) {
+ // Collect source positions immediately to try and flush out bytecode
+ // mismatches.
+ SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, shared_info);
+ }
+
if (shared_info.is_identical_to(top_level)) {
// Ensure that the top level function is retained.
*is_compiled_scope = shared_info->is_compiled_scope();
@@ -797,18 +806,10 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
return MaybeHandle<Code>();
}
- // If code was pending optimization for testing, delete remove the strong root
- // that was preventing the bytecode from being flushed between marking and
- // optimization.
- if (!isolate->heap()->pending_optimize_for_test_bytecode().IsUndefined()) {
- Handle<ObjectHashTable> table =
- handle(ObjectHashTable::cast(
- isolate->heap()->pending_optimize_for_test_bytecode()),
- isolate);
- bool was_present;
- table = table->Remove(isolate, table, handle(function->shared(), isolate),
- &was_present);
- isolate->heap()->SetPendingOptimizeForTestBytecode(*table);
+ // If code was pending optimization for testing, delete remove the entry
+ // from the table that was preventing the bytecode from being flushed
+ if (V8_UNLIKELY(FLAG_testing_d8_test_runner)) {
+ PendingOptimizationTable::FunctionWasOptimized(isolate, function);
}
Handle<Code> cached_code;
@@ -1346,6 +1347,13 @@ bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
DCHECK(!isolate->has_pending_exception());
*is_compiled_scope = shared_info->is_compiled_scope();
DCHECK(is_compiled_scope->is_compiled());
+
+ if (FLAG_stress_lazy_source_positions) {
+ // Collect source positions immediately to try and flush out bytecode
+ // mismatches.
+ SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, shared_info);
+ }
+
return true;
}
@@ -1599,33 +1607,103 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
return result;
}
-bool Compiler::CodeGenerationFromStringsAllowed(Isolate* isolate,
- Handle<Context> context,
- Handle<String> source) {
+// Check whether embedder allows code generation in this context.
+// (via v8::Isolate::SetAllowCodeGenerationFromStringsCallback)
+bool CodeGenerationFromStringsAllowed(Isolate* isolate, Handle<Context> context,
+ Handle<String> source) {
DCHECK(context->allow_code_gen_from_strings().IsFalse(isolate));
- // Check with callback if set.
+ DCHECK(isolate->allow_code_gen_callback());
+
+ // Callback set. Let it decide if code generation is allowed.
+ VMState<EXTERNAL> state(isolate);
+ RuntimeCallTimerScope timer(
+ isolate, RuntimeCallCounterId::kCodeGenerationFromStringsCallbacks);
AllowCodeGenerationFromStringsCallback callback =
isolate->allow_code_gen_callback();
- if (callback == nullptr) {
- // No callback set and code generation disallowed.
- return false;
- } else {
- // Callback set. Let it decide if code generation is allowed.
- VMState<EXTERNAL> state(isolate);
- return callback(v8::Utils::ToLocal(context), v8::Utils::ToLocal(source));
+ return callback(v8::Utils::ToLocal(context), v8::Utils::ToLocal(source));
+}
+
+// Check whether embedder allows code generation in this context.
+// (via v8::Isolate::SetModifyCodeGenerationFromStringsCallback)
+bool ModifyCodeGenerationFromStrings(Isolate* isolate, Handle<Context> context,
+ Handle<i::Object>* source) {
+ DCHECK(context->allow_code_gen_from_strings().IsFalse(isolate));
+ DCHECK(isolate->modify_code_gen_callback());
+ DCHECK(source);
+
+ // Callback set. Run it, and use the return value as source, or block
+ // execution if it's not set.
+ VMState<EXTERNAL> state(isolate);
+ ModifyCodeGenerationFromStringsCallback modify_callback =
+ isolate->modify_code_gen_callback();
+ RuntimeCallTimerScope timer(
+ isolate, RuntimeCallCounterId::kCodeGenerationFromStringsCallbacks);
+ MaybeLocal<v8::String> modified_source =
+ modify_callback(v8::Utils::ToLocal(context), v8::Utils::ToLocal(*source));
+ if (modified_source.IsEmpty()) return false;
+
+ // Use the new source (which might be the same as the old source) and return.
+ *source = Utils::OpenHandle(*modified_source.ToLocalChecked(), false);
+ return true;
+}
+
+// Run Embedder-mandated checks before generating code from a string.
+//
+// Returns a string to be used for compilation, or a flag that an object type
+// was encountered that is neither a string, nor something the embedder knows
+// how to handle.
+//
+// Returns: (assuming: std::tie(source, unknown_object))
+// - !source.is_null(): compilation allowed, source contains the source string.
+// - unknown_object is true: compilation allowed, but we don't know how to
+// deal with source_object.
+// - source.is_null() && !unknown_object: compilation should be blocked.
+//
+// - !source_is_null() and unknown_object can't be true at the same time.
+std::pair<MaybeHandle<String>, bool> Compiler::ValidateDynamicCompilationSource(
+ Isolate* isolate, Handle<Context> context,
+ Handle<i::Object> source_object) {
+ Handle<String> source;
+ if (source_object->IsString()) source = Handle<String>::cast(source_object);
+
+ // Check if the context unconditionally allows code gen from strings.
+ // allow_code_gen_from_strings can be many things, so we'll always check
+ // against the 'false' literal, so that e.g. undefined and 'true' are treated
+ // the same.
+ if (!context->allow_code_gen_from_strings().IsFalse(isolate)) {
+ return {source, !source_object->IsString()};
+ }
+
+ // Check if the context allows code generation for this string.
+ // allow_code_gen_callback only allows proper strings.
+ // (I.e., let allow_code_gen_callback decide, if it has been set.)
+ if (isolate->allow_code_gen_callback()) {
+ if (source_object->IsString() &&
+ CodeGenerationFromStringsAllowed(isolate, context, source)) {
+ return {source, !source_object->IsString()};
+ }
+ }
+
+ // Check if the context wants to block or modify this source object.
+ // Double-check that we really have a string now.
+ // (Let modify_code_gen_callback decide, if it's been set.)
+ if (isolate->modify_code_gen_callback()) {
+ if (ModifyCodeGenerationFromStrings(isolate, context, &source_object) &&
+ source_object->IsString())
+ return {Handle<String>::cast(source_object), false};
}
+
+ return {MaybeHandle<String>(), !source_object->IsString()};
}
-MaybeHandle<JSFunction> Compiler::GetFunctionFromString(
- Handle<Context> context, Handle<String> source,
+MaybeHandle<JSFunction> Compiler::GetFunctionFromValidatedString(
+ Handle<Context> context, MaybeHandle<String> source,
ParseRestriction restriction, int parameters_end_pos) {
Isolate* const isolate = context->GetIsolate();
Handle<Context> native_context(context->native_context(), isolate);
- // Check if native context allows code generation from
- // strings. Throw an exception if it doesn't.
- if (native_context->allow_code_gen_from_strings().IsFalse(isolate) &&
- !CodeGenerationFromStringsAllowed(isolate, native_context, source)) {
+ // Raise an EvalError if we did not receive a string.
+ if (source.is_null()) {
Handle<Object> error_message =
native_context->ErrorMessageForCodeGenerationFromStrings();
THROW_NEW_ERROR(
@@ -1639,9 +1717,20 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromString(
int eval_position = kNoSourcePosition;
Handle<SharedFunctionInfo> outer_info(
native_context->empty_function().shared(), isolate);
- return Compiler::GetFunctionFromEval(
- source, outer_info, native_context, LanguageMode::kSloppy, restriction,
- parameters_end_pos, eval_scope_position, eval_position);
+ return Compiler::GetFunctionFromEval(source.ToHandleChecked(), outer_info,
+ native_context, LanguageMode::kSloppy,
+ restriction, parameters_end_pos,
+ eval_scope_position, eval_position);
+}
+
+MaybeHandle<JSFunction> Compiler::GetFunctionFromString(
+ Handle<Context> context, Handle<Object> source,
+ ParseRestriction restriction, int parameters_end_pos) {
+ Isolate* const isolate = context->GetIsolate();
+ Handle<Context> native_context(context->native_context(), isolate);
+ return GetFunctionFromValidatedString(
+ context, ValidateDynamicCompilationSource(isolate, context, source).first,
+ restriction, parameters_end_pos);
}
namespace {