Сгенерированный код может быть выполнен разными способами. В классе GeneratedCode
есть операция Call
, в которой сгенерированный код может быть выполнен тремя разными маршрутами.
// Use this class either as {GeneratedCode<ret, arg1, arg2>} or
// {GeneratedCode<ret(arg1, arg2)>} (see specialization below).
template <typename Return, typename... Args>
class GeneratedCode {
public:
using Signature = Return(Args...);
static GeneratedCode FromAddress(Isolate* isolate, Address addr) {
return GeneratedCode(isolate, reinterpret_cast<Signature*>(addr));
}
static GeneratedCode FromBuffer(Isolate* isolate, uint8_t* buffer) {
return GeneratedCode(isolate, reinterpret_cast<Signature*>(buffer));
}
static GeneratedCode FromCode(Isolate* isolate, Tagged<Code> code) {
return FromAddress(isolate, code->instruction_start());
}
#ifdef USE_SIMULATOR
// Defined in simulator-base.h.
Return Call(Args... args) {
// Starboard is a platform abstraction interface that also include Windows
// platforms like UWP.
#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) && \
!defined(V8_OS_STARBOARD) && !defined(V8_TARGET_ARCH_ARM)
FATAL(
"Generated code execution not possible during cross-compilation."
"Also, generic C function calls are not implemented on 32-bit arm "
"yet.");
#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) &&
// !defined(V8_OS_STARBOARD) && !defined(V8_TARGET_ARCH_ARM)
return Simulator::current(isolate_)->template Call<Return>(
reinterpret_cast<Address>(fn_ptr_), args...);
}
#else
DISABLE_CFI_ICALL Return Call(Args... args) {
// When running without a simulator we call the entry directly.
// Starboard is a platform abstraction interface that also include Windows
// platforms like UWP.
#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) && \
!defined(V8_OS_STARBOARD)
FATAL("Generated code execution not possible during cross-compilation.");
#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN)
#if ABI_USES_FUNCTION_DESCRIPTORS
#if V8_OS_ZOS
// z/OS ABI requires function descriptors (FD). Artificially create a pseudo
// FD to ensure correct dispatch to generated code.
void* function_desc[2] = {0, reinterpret_cast<void*>(fn_ptr_)};
asm volatile(" stg 5,%0 " : "=m"(function_desc[0])::"r5");
Signature* fn = reinterpret_cast<Signature*>(function_desc);
return fn(args...);
#else
// AIX ABI requires function descriptors (FD). Artificially create a pseudo
// FD to ensure correct dispatch to generated code. The 'volatile'
// declaration is required to avoid the compiler from not observing the
// alias of the pseudo FD to the function pointer, and hence, optimizing the
// pseudo FD declaration/initialization away.
volatile Address function_desc[] = {reinterpret_cast<Address>(fn_ptr_), 0,
0};
Signature* fn = reinterpret_cast<Signature*>(function_desc);
return fn(args...);
#endif // V8_OS_ZOS
#else
return fn_ptr_(args...);
#endif // ABI_USES_FUNCTION_DESCRIPTORS
}
#endif // USE_SIMULATOR
private:
friend class GeneratedCode<Return(Args...)>;
Isolate* isolate_;
Signature* fn_ptr_;
GeneratedCode(Isolate* isolate, Signature* fn_ptr)
: isolate_(isolate), fn_ptr_(fn_ptr) {}
};
Первый способ — через симулятор:
return Simulator::current(isolate_)->template Call<Return>(reinterpret_cast<Address>(fn_ptr_), args...);
Второй без симулятора:
return fn(args...);
И третий без симулятора:
return fn_ptr_(args...);
Вопрос в следующем: почему существует так много маршрутов выполнения, чем они отличаются и когда используются?
@PepijnKramer Где мне тогда это спрашивать, в GitHub V8 нет места для вопросов.
Почему существует так много маршрутов выполнения, чем они отличаются и когда используются?
Симуляторы V8 предназначены для кроссплатформенного тестирования.
Остальные пути кода предназначены для требований конкретной платформы, как указывают комментарии и #ifdef
.
Это не лучший вопрос для Stackoverflow.
Я согласен, и мне жаль, что я поощрил это, дав ответы на несколько подобных вопросов, которые этому предшествовали. Итак, это будет мой последний ответ в этой серии вопросов «просто из любопытства, почему именно эти детали реализации реализованы таким образом?» вопросы.
Я понимаю, что изучение открытого исходного кода — это увлекательно, и вам определенно стоит продолжать этим заниматься. На самом деле, вы должны ожидать, что вам придется разбираться в большинстве вещей самостоятельно; вот почему я пытался помочь вам помочь себе, указав вам на codesearch. Если вы предпочитаете общаться с людьми, возможно, подумайте о том, чтобы создать рабочую группу с одним или двумя друзьями и вместе разобраться в запутанных моментах?
Иногда немного обоснованных догадок также имеет большое значение. Когда вы видите #ifdef V8_OS_ZOS
, вам действительно не нужно, чтобы кто-то говорил вам, что этот код используется в z/OS, не так ли?
Возможно, вам следует поместить часть 2 в часть 1 и наоборот. Основной ответ (часть 2) следует поставить первым.
@user12002570 user12002570 Как пожелаете. Сделанный.
@jmrk То есть режим симулятора не используется при классической работе двигателя V8? Это последнее, что я хочу уточнить, после этого я принимаю ответ и заканчиваю обсуждение.
@MaximPro Правильно, симуляторы не используются в производстве (они слишком медленные для этого).
@jmrk Спасибо за ваши ответы и за то, что не оставили меня с ними наедине, я очень ценю это. Хорошего дня.
Это не лучший вопрос для Stackoverflow, поскольку это не вопрос о коде, который вы написали и/или отладили самостоятельно. Единственный, кто действительно знает, это разработчик библиотеки (и, возможно, это есть в документации), так что вам придется спрашивать там.