зеркало из https://github.com/github/ruby.git
Remove obsoleted MJIT_HEADER macro
This commit is contained in:
Родитель
7fb36a0054
Коммит
290e26c729
|
@ -81,10 +81,8 @@
|
|||
#undef NOINLINE
|
||||
#define NOINLINE(x) RBIMPL_ATTR_NOINLINE() x
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
# undef ALWAYS_INLINE
|
||||
# define ALWAYS_INLINE(x) RBIMPL_ATTR_FORCEINLINE() x
|
||||
#endif
|
||||
#undef ALWAYS_INLINE
|
||||
#define ALWAYS_INLINE(x) RBIMPL_ATTR_FORCEINLINE() x
|
||||
|
||||
#undef ERRORFUNC
|
||||
#define ERRORFUNC(mesg, x) RBIMPL_ATTR_ERROR(mesg) x
|
||||
|
|
|
@ -37,9 +37,7 @@
|
|||
* ```
|
||||
*/
|
||||
#undef RUBY_EXTERN
|
||||
#if defined(MJIT_HEADER) && defined(_WIN32)
|
||||
# define RUBY_EXTERN extern __declspec(dllimport)
|
||||
#elif defined(RUBY_EXPORT)
|
||||
#if defined(RUBY_EXPORT)
|
||||
# define RUBY_EXTERN extern
|
||||
#elif defined(_WIN32)
|
||||
# define RUBY_EXTERN extern __declspec(dllimport)
|
||||
|
|
|
@ -1345,10 +1345,8 @@ opt_aset_with
|
|||
val = tmp;
|
||||
}
|
||||
else {
|
||||
#ifndef MJIT_HEADER
|
||||
TOPN(0) = rb_str_resurrect(key);
|
||||
PUSH(val);
|
||||
#endif
|
||||
CALL_SIMPLE_METHOD();
|
||||
}
|
||||
}
|
||||
|
@ -1365,9 +1363,7 @@ opt_aref_with
|
|||
val = vm_opt_aref_with(recv, key);
|
||||
|
||||
if (val == Qundef) {
|
||||
#ifndef MJIT_HEADER
|
||||
PUSH(rb_str_resurrect(key));
|
||||
#endif
|
||||
CALL_SIMPLE_METHOD();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,7 @@
|
|||
# include <stdlib.h> /* for _byteswap_uint64 */
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_X86INTRIN_H) && ! defined(MJIT_HEADER)
|
||||
# /* Rule out MJIT_HEADER, which does not interface well with <immintrin.h> */
|
||||
#if defined(HAVE_X86INTRIN_H)
|
||||
# include <x86intrin.h> /* for _lzcnt_u64 */
|
||||
#elif MSC_VERSION_SINCE(1310)
|
||||
# include <intrin.h> /* for the following intrinsics */
|
||||
|
@ -235,7 +234,7 @@ nlz_int32(uint32_t x)
|
|||
* safety. */
|
||||
return (unsigned int)__lzcnt(x);
|
||||
|
||||
#elif defined(__x86_64__) && defined(__LZCNT__) && ! defined(MJIT_HEADER)
|
||||
#elif defined(__x86_64__) && defined(__LZCNT__)
|
||||
return (unsigned int)_lzcnt_u32(x);
|
||||
|
||||
#elif MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
|
||||
|
@ -264,7 +263,7 @@ nlz_int64(uint64_t x)
|
|||
#if defined(_MSC_VER) && defined(__AVX2__)
|
||||
return (unsigned int)__lzcnt64(x);
|
||||
|
||||
#elif defined(__x86_64__) && defined(__LZCNT__) && ! defined(MJIT_HEADER)
|
||||
#elif defined(__x86_64__) && defined(__LZCNT__)
|
||||
return (unsigned int)_lzcnt_u64(x);
|
||||
|
||||
#elif defined(_WIN64) && MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
|
||||
|
@ -450,7 +449,7 @@ rb_popcount_intptr(uintptr_t x)
|
|||
static inline int
|
||||
ntz_int32(uint32_t x)
|
||||
{
|
||||
#if defined(__x86_64__) && defined(__BMI__) && ! defined(MJIT_HEADER)
|
||||
#if defined(__x86_64__) && defined(__BMI__)
|
||||
return (unsigned)_tzcnt_u32(x);
|
||||
|
||||
#elif MSC_VERSION_SINCE(1400)
|
||||
|
@ -472,7 +471,7 @@ ntz_int32(uint32_t x)
|
|||
static inline int
|
||||
ntz_int64(uint64_t x)
|
||||
{
|
||||
#if defined(__x86_64__) && defined(__BMI__) && ! defined(MJIT_HEADER)
|
||||
#if defined(__x86_64__) && defined(__BMI__)
|
||||
return (unsigned)_tzcnt_u64(x);
|
||||
|
||||
#elif defined(_WIN64) && MSC_VERSION_SINCE(1400)
|
||||
|
|
|
@ -89,8 +89,6 @@
|
|||
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
|
||||
#endif
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
|
||||
/*!
|
||||
* This function asserts that a (continuous) memory region from ptr to size
|
||||
* being "poisoned". Both read / write access to such memory region are
|
||||
|
@ -185,6 +183,4 @@ asan_unpoison_object(VALUE obj, bool newobj_p)
|
|||
asan_unpoison_memory_region(ptr, SIZEOF_VALUE, newobj_p);
|
||||
}
|
||||
|
||||
#endif /* MJIT_HEADER */
|
||||
|
||||
#endif /* INTERNAL_SANITIZERS_H */
|
||||
|
|
14
vm.c
14
vm.c
|
@ -43,11 +43,7 @@
|
|||
|
||||
#include "builtin.h"
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
#include "probes.h"
|
||||
#else
|
||||
#include "probes.dmyh"
|
||||
#endif
|
||||
#include "probes_helper.h"
|
||||
|
||||
#ifdef RUBY_ASSERT_CRITICAL_SECTION
|
||||
|
@ -422,14 +418,10 @@ jit_exec(rb_execution_context_t *ec)
|
|||
|
||||
#include "vm_insnhelper.c"
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
|
||||
#include "vm_exec.c"
|
||||
|
||||
#include "vm_method.c"
|
||||
#endif /* #ifndef MJIT_HEADER */
|
||||
#include "vm_eval.c"
|
||||
#ifndef MJIT_HEADER
|
||||
|
||||
#define PROCDEBUG 0
|
||||
|
||||
|
@ -688,8 +680,6 @@ rb_vm_get_ruby_level_next_cfp(const rb_execution_context_t *ec, const rb_control
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif /* #ifndef MJIT_HEADER */
|
||||
|
||||
static rb_control_frame_t *
|
||||
vm_get_ruby_level_caller_cfp(const rb_execution_context_t *ec, const rb_control_frame_t *cfp)
|
||||
{
|
||||
|
@ -724,8 +714,6 @@ rb_vm_pop_cfunc_frame(void)
|
|||
vm_pop_frame(ec, cfp, cfp->ep);
|
||||
}
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
|
||||
void
|
||||
rb_vm_rewind_cfp(rb_execution_context_t *ec, rb_control_frame_t *cfp)
|
||||
{
|
||||
|
@ -4424,6 +4412,4 @@ rb_vm_empty_cc_for_super(void)
|
|||
return &vm_empty_cc_for_super;
|
||||
}
|
||||
|
||||
#endif /* #ifndef MJIT_HEADER */
|
||||
|
||||
#include "vm_call_iseq_optimized.inc" /* required from vm_insnhelper.c */
|
||||
|
|
12
vm_eval.c
12
vm_eval.c
|
@ -41,8 +41,6 @@ typedef enum call_type {
|
|||
static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
|
||||
static VALUE vm_call0_body(rb_execution_context_t* ec, struct rb_calling_info *calling, const VALUE *argv);
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
|
||||
VALUE
|
||||
rb_vm_call0(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *cme, int kw_splat)
|
||||
{
|
||||
|
@ -352,8 +350,6 @@ rb_current_receiver(void)
|
|||
return cfp->self;
|
||||
}
|
||||
|
||||
#endif /* #ifndef MJIT_HEADER */
|
||||
|
||||
static inline void
|
||||
stack_check(rb_execution_context_t *ec)
|
||||
{
|
||||
|
@ -364,8 +360,6 @@ stack_check(rb_execution_context_t *ec)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
|
||||
void
|
||||
rb_check_stack_overflow(void)
|
||||
{
|
||||
|
@ -944,8 +938,6 @@ rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* #ifndef MJIT_HEADER */
|
||||
|
||||
static void
|
||||
raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE obj,
|
||||
enum method_missing_reason last_call_status)
|
||||
|
@ -1035,8 +1027,6 @@ method_missing(rb_execution_context_t *ec, VALUE obj, ID id, int argc, const VAL
|
|||
UNREACHABLE_RETURN(Qundef);
|
||||
}
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
|
||||
static inline VALUE
|
||||
rb_funcallv_scope(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
|
||||
{
|
||||
|
@ -2551,5 +2541,3 @@ Init_vm_eval(void)
|
|||
id_tag = rb_intern_const("tag");
|
||||
id_value = rb_intern_const("value");
|
||||
}
|
||||
|
||||
#endif /* #ifndef MJIT_HEADER */
|
||||
|
|
|
@ -165,12 +165,6 @@ default: \
|
|||
|
||||
#define VM_SP_CNT(ec, sp) ((sp) - (ec)->vm_stack)
|
||||
|
||||
#ifdef MJIT_HEADER
|
||||
#define THROW_EXCEPTION(exc) do { \
|
||||
ec->errinfo = (VALUE)(exc); \
|
||||
EC_JUMP_TAG(ec, ec->tag->state); \
|
||||
} while (0)
|
||||
#else
|
||||
#if OPT_CALL_THREADED_CODE
|
||||
#define THROW_EXCEPTION(exc) do { \
|
||||
ec->errinfo = (VALUE)(exc); \
|
||||
|
@ -179,7 +173,6 @@ default: \
|
|||
#else
|
||||
#define THROW_EXCEPTION(exc) return (VALUE)(exc)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SCREG(r) (reg_##r)
|
||||
|
||||
|
|
|
@ -27,9 +27,7 @@
|
|||
|
||||
/* finish iseq array */
|
||||
#include "insns.inc"
|
||||
#ifndef MJIT_HEADER
|
||||
#include "insns_info.inc"
|
||||
#endif
|
||||
|
||||
extern rb_method_definition_t *rb_method_definition_create(rb_method_type_t type, ID mid);
|
||||
extern void rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts);
|
||||
|
@ -37,10 +35,8 @@ extern int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_me
|
|||
extern VALUE rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
|
||||
int argc, const VALUE *argv, int priv);
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
static const struct rb_callcache vm_empty_cc;
|
||||
static const struct rb_callcache vm_empty_cc_for_super;
|
||||
#endif
|
||||
|
||||
/* control stack frame */
|
||||
|
||||
|
@ -71,9 +67,6 @@ ec_stack_overflow(rb_execution_context_t *ec, int setup)
|
|||
}
|
||||
|
||||
NORETURN(static void vm_stackoverflow(void));
|
||||
#ifdef MJIT_HEADER
|
||||
NOINLINE(static COLDFUNC void vm_stackoverflow(void));
|
||||
#endif
|
||||
|
||||
static void
|
||||
vm_stackoverflow(void)
|
||||
|
@ -239,7 +232,6 @@ vm_check_frame(VALUE type,
|
|||
static VALUE vm_stack_canary; /* Initialized later */
|
||||
static bool vm_stack_canary_was_born = false;
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
void
|
||||
rb_vm_check_canary(const rb_execution_context_t *ec, VALUE *sp)
|
||||
{
|
||||
|
@ -287,7 +279,6 @@ rb_vm_check_canary(const rb_execution_context_t *ec, VALUE *sp)
|
|||
name, stri, pos, strd);
|
||||
rb_bug("see above.");
|
||||
}
|
||||
#endif
|
||||
#define vm_check_canary(ec, sp) rb_vm_check_canary(ec, sp)
|
||||
|
||||
#else
|
||||
|
@ -1981,8 +1972,6 @@ vm_ccs_verify(struct rb_class_cc_entries *ccs, ID mid, VALUE klass)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
|
||||
static const rb_callable_method_entry_t *check_overloaded_cme(const rb_callable_method_entry_t *cme, const struct rb_callinfo * const ci);
|
||||
|
||||
static const struct rb_callcache *
|
||||
|
@ -2103,7 +2092,6 @@ rb_vm_search_method_slowpath(const struct rb_callinfo *ci, VALUE klass)
|
|||
|
||||
return cc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct rb_callcache *
|
||||
vm_search_method_slowpath0(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
|
||||
|
@ -2117,12 +2105,7 @@ vm_search_method_slowpath0(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
|
|||
#if OPT_INLINE_METHOD_CACHE
|
||||
cd->cc = cc;
|
||||
|
||||
const struct rb_callcache *empty_cc =
|
||||
#ifdef MJIT_HEADER
|
||||
rb_vm_empty_cc();
|
||||
#else
|
||||
&vm_empty_cc;
|
||||
#endif
|
||||
const struct rb_callcache *empty_cc = &vm_empty_cc;
|
||||
if (cd_owner && cc != empty_cc) RB_OBJ_WRITTEN(cd_owner, Qundef, cc);
|
||||
|
||||
#if USE_DEBUG_COUNTER
|
||||
|
@ -2152,9 +2135,7 @@ vm_search_method_slowpath0(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
|
|||
return cc;
|
||||
}
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
ALWAYS_INLINE(static const struct rb_callcache *vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass));
|
||||
#endif
|
||||
static const struct rb_callcache *
|
||||
vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
|
||||
{
|
||||
|
@ -2340,8 +2321,6 @@ opt_equality(const rb_iseq_t *cd_owner, VALUE recv, VALUE obj, CALL_DATA cd)
|
|||
|
||||
#undef EQ_UNREDEFINED_P
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
|
||||
static inline const struct rb_callcache *gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, int argc); // vm_eval.c
|
||||
NOINLINE(static VALUE opt_equality_by_mid_slowpath(VALUE recv, VALUE obj, ID mid));
|
||||
|
||||
|
@ -2382,8 +2361,6 @@ rb_eql_opt(VALUE obj1, VALUE obj2)
|
|||
return opt_equality_by_mid(obj1, obj2, idEqlP);
|
||||
}
|
||||
|
||||
#endif // MJIT_HEADER
|
||||
|
||||
extern VALUE rb_vm_call0(rb_execution_context_t *ec, VALUE, ID, int, const VALUE*, const rb_callable_method_entry_t *, int kw_splat);
|
||||
extern VALUE rb_vm_call_with_refinements(rb_execution_context_t *, VALUE, ID, int, const VALUE *, int);
|
||||
|
||||
|
@ -4319,11 +4296,7 @@ vm_super_outside(void)
|
|||
static const struct rb_callcache *
|
||||
empty_cc_for_super(void)
|
||||
{
|
||||
#ifdef MJIT_HEADER
|
||||
return rb_vm_empty_cc_for_super();
|
||||
#else
|
||||
return &vm_empty_cc_for_super;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct rb_callcache *
|
||||
|
@ -5195,52 +5168,19 @@ vm_invokeblock_i(struct rb_execution_context_struct *ec,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MJIT_HEADER
|
||||
static const struct rb_callcache *
|
||||
vm_search_method_wrap(const struct rb_control_frame_struct *reg_cfp, struct rb_call_data *cd, VALUE recv)
|
||||
{
|
||||
return vm_search_method((VALUE)reg_cfp->iseq, cd, recv);
|
||||
}
|
||||
|
||||
static const struct rb_callcache *
|
||||
vm_search_invokeblock(const struct rb_control_frame_struct *reg_cfp, struct rb_call_data *cd, VALUE recv)
|
||||
{
|
||||
static const struct rb_callcache cc = {
|
||||
.flags = T_IMEMO | (imemo_callcache << FL_USHIFT) | VM_CALLCACHE_UNMARKABLE,
|
||||
.klass = 0,
|
||||
.cme_ = 0,
|
||||
.call_ = vm_invokeblock_i,
|
||||
.aux_ = {0},
|
||||
};
|
||||
return &cc;
|
||||
}
|
||||
|
||||
# define mexp_search_method vm_search_method_wrap
|
||||
# define mexp_search_super vm_search_super_method
|
||||
# define mexp_search_invokeblock vm_search_invokeblock
|
||||
#else
|
||||
enum method_explorer_type {
|
||||
mexp_search_method,
|
||||
mexp_search_invokeblock,
|
||||
mexp_search_super,
|
||||
};
|
||||
#endif
|
||||
|
||||
static
|
||||
#ifndef MJIT_HEADER
|
||||
inline
|
||||
#endif
|
||||
VALUE
|
||||
static inline VALUE
|
||||
vm_sendish(
|
||||
struct rb_execution_context_struct *ec,
|
||||
struct rb_control_frame_struct *reg_cfp,
|
||||
struct rb_call_data *cd,
|
||||
VALUE block_handler,
|
||||
#ifdef MJIT_HEADER
|
||||
const struct rb_callcache *(*method_explorer)(const struct rb_control_frame_struct *cfp, struct rb_call_data *cd, VALUE recv)
|
||||
#else
|
||||
enum method_explorer_type method_explorer
|
||||
#endif
|
||||
) {
|
||||
VALUE val = Qundef;
|
||||
const struct rb_callinfo *ci = cd->ci;
|
||||
|
@ -5255,11 +5195,6 @@ vm_sendish(
|
|||
.ci = ci,
|
||||
};
|
||||
|
||||
// The enum-based branch and inlining are faster in VM, but function pointers without inlining are faster in JIT.
|
||||
#ifdef MJIT_HEADER
|
||||
calling.cc = cc = method_explorer(GET_CFP(), cd, recv);
|
||||
val = vm_cc_call(cc)(ec, GET_CFP(), &calling);
|
||||
#else
|
||||
switch (method_explorer) {
|
||||
case mexp_search_method:
|
||||
calling.cc = cc = vm_search_method_fastpath((VALUE)reg_cfp->iseq, cd, CLASS_OF(recv));
|
||||
|
@ -5274,7 +5209,6 @@ vm_sendish(
|
|||
val = vm_invokeblock_i(ec, GET_CFP(), &calling);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!UNDEF_P(val)) {
|
||||
return val; /* CFUNC normal return */
|
||||
|
@ -5283,29 +5217,7 @@ vm_sendish(
|
|||
RESTORE_REGS(); /* CFP pushed in cc->call() */
|
||||
}
|
||||
|
||||
#ifdef MJIT_HEADER
|
||||
/* When calling ISeq which may catch an exception from JIT-ed
|
||||
code, we should not call jit_exec directly to prevent the
|
||||
caller frame from being canceled. That's because the caller
|
||||
frame may have stack values in the local variables and the
|
||||
cancelling the caller frame will purge them. But directly
|
||||
calling jit_exec is faster... */
|
||||
if (ISEQ_BODY(GET_ISEQ())->catch_except_p) {
|
||||
VM_ENV_FLAGS_SET(GET_EP(), VM_FRAME_FLAG_FINISH);
|
||||
return vm_exec(ec, true);
|
||||
}
|
||||
else if (UNDEF_P(val = jit_exec(ec))) {
|
||||
VM_ENV_FLAGS_SET(GET_EP(), VM_FRAME_FLAG_FINISH);
|
||||
return vm_exec(ec, false);
|
||||
}
|
||||
else {
|
||||
return val;
|
||||
}
|
||||
#else
|
||||
/* When calling from VM, longjmp in the callee won't purge any
|
||||
JIT-ed caller frames. So it's safe to directly call jit_exec. */
|
||||
return jit_exec(ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* object.c */
|
||||
|
@ -6298,7 +6210,6 @@ Init_vm_stack_canary(void)
|
|||
VM_ASSERT(n == 0);
|
||||
}
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
void
|
||||
rb_vm_canary_is_found_dead(enum ruby_vminsn_type i, VALUE c)
|
||||
{
|
||||
|
@ -6310,7 +6221,6 @@ rb_vm_canary_is_found_dead(enum ruby_vminsn_type i, VALUE c)
|
|||
|
||||
rb_bug("dead canary found at %s: %s", insn, str);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
void Init_vm_stack_canary(void) { /* nothing to do */ }
|
||||
|
|
|
@ -181,7 +181,6 @@ CC_SET_FASTPATH(const struct rb_callcache *cc, vm_call_handler func, bool enable
|
|||
/* others */
|
||||
/**********************************************************/
|
||||
|
||||
#ifndef MJIT_HEADER
|
||||
#define CALL_SIMPLE_METHOD() do { \
|
||||
rb_snum_t x = leaf ? INSN_ATTR(width) : 0; \
|
||||
rb_snum_t y = attr_width_opt_send_without_block(0); \
|
||||
|
@ -189,7 +188,6 @@ CC_SET_FASTPATH(const struct rb_callcache *cc, vm_call_handler func, bool enable
|
|||
ADD_PC(z); \
|
||||
DISPATCH_ORIGINAL_INSN(opt_send_without_block); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define GET_GLOBAL_CVAR_STATE() (ruby_vm_global_cvar_state)
|
||||
#define INC_GLOBAL_CVAR_STATE() (++ruby_vm_global_cvar_state)
|
||||
|
|
2
yjit.h
2
yjit.h
|
@ -15,7 +15,7 @@
|
|||
# define YJIT_STATS RUBY_DEBUG
|
||||
#endif
|
||||
|
||||
#if USE_YJIT && !defined(MJIT_HEADER) // MJIT and YJIT can't be enabled simultaneously
|
||||
#if USE_YJIT
|
||||
|
||||
// We generate x86 or arm64 assembly
|
||||
#if defined(_WIN32) ? defined(_M_AMD64) : (defined(__x86_64__) || defined(__aarch64__))
|
||||
|
|
Загрузка…
Ссылка в новой задаче