[builtins] Port Frame-related CSA functionality to Torque
Moving Frame-inspection functionality to Torque is a prerequisite for porting the CSA-based arguments code, which is a great candidate to simplify/cleanup with Torque. Change-Id: I1f4cb94cb357aae5864c2e84f3bf5a07549b27f8 Reviewed-on: https://chromium-review.googlesource.com/c/1357050 Commit-Queue: Daniel Clifford <danno@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#58106}
This commit is contained in:
parent
03ea675422
commit
9362fa9478
1
BUILD.gn
1
BUILD.gn
@ -959,6 +959,7 @@ torque_files = [
|
||||
"src/builtins/array-unshift.tq",
|
||||
"src/builtins/collections.tq",
|
||||
"src/builtins/data-view.tq",
|
||||
"src/builtins/frames.tq",
|
||||
"src/builtins/object.tq",
|
||||
"src/builtins/object-fromentries.tq",
|
||||
"src/builtins/iterator.tq",
|
||||
|
@ -15,8 +15,8 @@ type Arguments constexpr 'CodeStubArguments*';
|
||||
type void;
|
||||
type never;
|
||||
|
||||
type Tagged generates 'TNode<Object>' constexpr 'Object*';
|
||||
type Smi extends Tagged generates 'TNode<Smi>' constexpr 'Smi*';
|
||||
type Tagged generates 'TNode<Object>' constexpr 'ObjectPtr';
|
||||
type Smi extends Tagged generates 'TNode<Smi>' constexpr 'Smi';
|
||||
type HeapObject extends Tagged generates 'TNode<HeapObject>';
|
||||
type Object = Smi | HeapObject;
|
||||
type int32 generates 'TNode<Int32T>' constexpr 'int32_t';
|
||||
@ -128,6 +128,8 @@ type ToIntegerTruncationMode
|
||||
constexpr 'CodeStubAssembler::ToIntegerTruncationMode';
|
||||
type AllocationFlags constexpr 'AllocationFlags';
|
||||
|
||||
const kSmiTagSize: constexpr int31 generates 'kSmiTagSize';
|
||||
|
||||
const NO_ELEMENTS: constexpr ElementsKind generates 'NO_ELEMENTS';
|
||||
|
||||
const PACKED_SMI_ELEMENTS:
|
||||
@ -345,6 +347,10 @@ extern transitioning runtime TransitionElementsKindWithKind(
|
||||
extern transitioning runtime CreateDataProperty(implicit context: Context)(
|
||||
JSReceiver, Object, Object);
|
||||
|
||||
extern macro LoadBufferObject(RawPtr, constexpr int32): Object;
|
||||
extern macro LoadBufferPointer(RawPtr, constexpr int32): RawPtr;
|
||||
extern macro LoadBufferSmi(RawPtr, constexpr int32): Smi;
|
||||
|
||||
extern macro LoadRoot(constexpr RootIndex): Object;
|
||||
extern macro StoreRoot(constexpr RootIndex, Object): Object;
|
||||
extern macro LoadAndUntagToWord32Root(constexpr RootIndex): int32;
|
||||
@ -357,6 +363,9 @@ extern macro SmiLexicographicCompare(Smi, Smi): Smi;
|
||||
extern runtime ReThrow(Context, Object): never;
|
||||
extern runtime ThrowInvalidStringLength(Context): never;
|
||||
|
||||
extern operator '==' macro WordEqual(RawPtr, RawPtr): bool;
|
||||
extern operator '!=' macro WordNotEqual(RawPtr, RawPtr): bool;
|
||||
|
||||
extern operator '<' macro Int32LessThan(int32, int32): bool;
|
||||
extern operator '<' macro Uint32LessThan(uint32, uint32): bool;
|
||||
extern operator '>' macro Int32GreaterThan(int32, int32): bool;
|
||||
@ -433,21 +442,21 @@ extern operator '+' macro SmiAdd(Smi, Smi): Smi;
|
||||
extern operator '-' macro SmiSub(Smi, Smi): Smi;
|
||||
extern operator '&' macro SmiAnd(Smi, Smi): Smi;
|
||||
extern operator '|' macro SmiOr(Smi, Smi): Smi;
|
||||
extern operator '>>>' macro SmiShr(Smi, constexpr int31): Smi;
|
||||
extern operator '<<' macro SmiShl(Smi, constexpr int31): Smi;
|
||||
extern operator '>>' macro SmiSar(Smi, constexpr int31): Smi;
|
||||
|
||||
extern operator '+' macro IntPtrAdd(intptr, intptr): intptr;
|
||||
extern operator '-' macro IntPtrSub(intptr, intptr): intptr;
|
||||
extern operator '*' macro IntPtrMul(intptr, intptr): intptr;
|
||||
extern operator '/' macro IntPtrDiv(intptr, intptr): intptr;
|
||||
extern operator '<<' macro WordShl(intptr, intptr): intptr;
|
||||
extern operator '>>' macro WordSar(intptr, intptr): intptr;
|
||||
extern operator '&' macro WordAnd(intptr, intptr): intptr;
|
||||
extern operator '|' macro WordOr(intptr, intptr): intptr;
|
||||
|
||||
extern operator '+' macro UintPtrAdd(uintptr, uintptr): uintptr;
|
||||
extern operator '-' macro UintPtrSub(uintptr, uintptr): uintptr;
|
||||
extern operator '>>>' macro WordShr(uintptr, uintptr): uintptr;
|
||||
extern operator '<<' macro WordShl(uintptr, uintptr): uintptr;
|
||||
extern operator '&' macro WordAnd(uintptr, uintptr): uintptr;
|
||||
extern operator '|' macro WordOr(uintptr, uintptr): uintptr;
|
||||
|
||||
@ -487,6 +496,11 @@ macro Max(x: Number, y: Number): Number {
|
||||
return NumberMax(x, y);
|
||||
}
|
||||
|
||||
extern operator '<<' macro ConstexprUintPtrShl(
|
||||
constexpr uintptr, constexpr int31): constexpr uintptr;
|
||||
extern operator '>>>' macro ConstexprUintPtrShr(
|
||||
constexpr uintptr, constexpr int31): constexpr uintptr;
|
||||
|
||||
extern macro SmiMax(Smi, Smi): Smi;
|
||||
extern macro SmiMin(Smi, Smi): Smi;
|
||||
|
||||
@ -740,6 +754,7 @@ extern macro Int32Constant(constexpr int31): int31;
|
||||
extern macro Int32Constant(constexpr int32): int32;
|
||||
extern macro Float64Constant(constexpr int31): float64;
|
||||
extern macro SmiConstant(constexpr int31): Smi;
|
||||
extern macro SmiConstant(constexpr Smi): Smi;
|
||||
extern macro BoolConstant(constexpr bool): bool;
|
||||
extern macro StringConstant(constexpr string): String;
|
||||
extern macro LanguageModeConstant(constexpr LanguageMode): LanguageMode;
|
||||
@ -748,7 +763,10 @@ extern macro IntPtrConstant(constexpr NativeContextSlot): NativeContextSlot;
|
||||
extern macro IntPtrConstant(constexpr intptr): intptr;
|
||||
|
||||
extern macro BitcastWordToTaggedSigned(intptr): Smi;
|
||||
extern macro BitcastWordToTaggedSigned(uintptr): Smi;
|
||||
extern macro BitcastWordToTagged(intptr): Object;
|
||||
extern macro BitcastWordToTagged(uintptr): Object;
|
||||
extern macro BitcastTaggedToWord(Tagged): intptr;
|
||||
|
||||
intrinsic %FromConstexpr<To: type, From: type>(b: From): To;
|
||||
macro FromConstexpr<To: type, From: type>(o: From): To;
|
||||
@ -767,6 +785,12 @@ FromConstexpr<intptr, constexpr int31>(i: constexpr int31): intptr {
|
||||
FromConstexpr<intptr, constexpr int32>(i: constexpr int32): intptr {
|
||||
return %FromConstexpr<intptr>(i);
|
||||
}
|
||||
FromConstexpr<intptr, constexpr intptr>(i: constexpr intptr): intptr {
|
||||
return %FromConstexpr<intptr>(i);
|
||||
}
|
||||
FromConstexpr<uintptr, constexpr uintptr>(i: constexpr uintptr): uintptr {
|
||||
return %FromConstexpr<uintptr>(i);
|
||||
}
|
||||
FromConstexpr<Smi, constexpr int31>(i: constexpr int31): Smi {
|
||||
return %FromConstexpr<Smi>(i);
|
||||
}
|
||||
@ -785,6 +809,12 @@ FromConstexpr<Number, constexpr float64>(f: constexpr float64): Number {
|
||||
FromConstexpr<Number, constexpr int31>(i: constexpr int31): Number {
|
||||
return %FromConstexpr<Number>(i);
|
||||
}
|
||||
FromConstexpr<Number, constexpr Smi>(s: constexpr Smi): Number {
|
||||
return SmiConstant(s);
|
||||
}
|
||||
FromConstexpr<Smi, constexpr Smi>(s: constexpr Smi): Smi {
|
||||
return SmiConstant(s);
|
||||
}
|
||||
|
||||
FromConstexpr<uint32, constexpr int31>(i: constexpr int31): uint32 {
|
||||
return Unsigned(Int32Constant(i));
|
||||
@ -890,6 +920,9 @@ Convert<Number>(ui: uintptr): Number {
|
||||
Convert<uintptr>(d: float64): uintptr {
|
||||
return ChangeFloat64ToUintPtr(d);
|
||||
}
|
||||
Convert<uintptr>(i: intptr): uintptr {
|
||||
return Unsigned(i);
|
||||
}
|
||||
macro Convert<A: type>(r: RawPtr): A;
|
||||
Convert<uintptr>(r: RawPtr): uintptr {
|
||||
return Unsigned(r);
|
||||
@ -1175,7 +1208,6 @@ extern macro IsCustomElementsReceiverInstanceType(int32): bool;
|
||||
extern macro IsFastJSArrayWithNoCustomIteration(implicit context: Context)(
|
||||
Object): bool;
|
||||
extern macro Typeof(Object): Object;
|
||||
extern macro LoadTargetFromFrame(): JSFunction;
|
||||
|
||||
// Return true iff number is NaN.
|
||||
macro NumberIsNaN(number: Number): bool {
|
||||
|
150
src/builtins/frames.tq
Normal file
150
src/builtins/frames.tq
Normal file
@ -0,0 +1,150 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
type FrameType extends Smi
|
||||
generates 'TNode<Smi>' constexpr 'StackFrame::Type';
|
||||
const ARGUMENTS_ADAPTOR_FRAME: constexpr FrameType
|
||||
generates 'StackFrame::ARGUMENTS_ADAPTOR';
|
||||
const STUB_FRAME: constexpr FrameType
|
||||
generates 'StackFrame::STUB';
|
||||
const kFrameTypeCount:
|
||||
constexpr int31 generates 'StackFrame::NUMBER_OF_TYPES';
|
||||
|
||||
FromConstexpr<FrameType, constexpr FrameType>(t: constexpr FrameType):
|
||||
FrameType {
|
||||
// Note that althought FrameTypes sometimes masquerade as Smis (their
|
||||
// LSB is a zero), they are not. For efficiency in storing them as a
|
||||
// constant into a frame, they are simply the FrameType value shifted
|
||||
// up by a single bit.
|
||||
const i: constexpr uintptr = %RawConstexprCast<constexpr uintptr>(t)
|
||||
<< kSmiTagSize;
|
||||
return %RawObjectCast<FrameType>(BitcastWordToTaggedSigned(i));
|
||||
}
|
||||
Cast<FrameType>(o: Object): FrameType
|
||||
labels CastError {
|
||||
if (TaggedIsNotSmi(o)) goto CastError;
|
||||
assert(
|
||||
(Convert<uintptr>(BitcastTaggedToWord(o)) >>> kSmiTagSize) <
|
||||
kFrameTypeCount);
|
||||
return %RawObjectCast<FrameType>(o);
|
||||
}
|
||||
|
||||
type FrameBase extends RawPtr
|
||||
generates 'TNode<RawPtrT>' constexpr 'void*';
|
||||
type StandardFrame extends FrameBase
|
||||
generates 'TNode<RawPtrT>' constexpr 'void*';
|
||||
type ArgumentsAdapterFrame extends FrameBase
|
||||
generates 'TNode<RawPtrT>' constexpr 'void*';
|
||||
type StubFrame extends FrameBase
|
||||
generates 'TNode<RawPtrT>' constexpr 'void*';
|
||||
type Frame = ArgumentsAdapterFrame | StandardFrame | StubFrame;
|
||||
|
||||
extern macro LoadFramePointer(): Frame;
|
||||
extern macro LoadParentFramePointer(): Frame;
|
||||
|
||||
// Load values from a specified frame by given offset in bytes.
|
||||
macro LoadObjectFromFrame(f: Frame, o: constexpr int32): Object {
|
||||
return LoadBufferObject(f, o);
|
||||
}
|
||||
macro LoadPointerFromFrame(f: Frame, o: constexpr int32): RawPtr {
|
||||
return LoadBufferPointer(f, o);
|
||||
}
|
||||
macro LoadSmiFromFrame(f: Frame, o: constexpr int32): Smi {
|
||||
return LoadBufferSmi(f, o);
|
||||
}
|
||||
|
||||
const kStandardFrameFunctionOffset: constexpr int31
|
||||
generates 'StandardFrameConstants::kFunctionOffset';
|
||||
operator '.function' macro LoadFunctionFromFrame(f: Frame): JSFunction {
|
||||
// TODO(danno): Use RawObjectCast here in order to avoid passing the implicit
|
||||
// context, since this accessor is used in legacy CSA code through
|
||||
// LoadTargetFromFrame
|
||||
const result: Object = LoadObjectFromFrame(f, kStandardFrameFunctionOffset);
|
||||
return %RawObjectCast<JSFunction>(result);
|
||||
}
|
||||
|
||||
const kStandardFrameCallerFPOffset: constexpr int31
|
||||
generates 'StandardFrameConstants::kCallerFPOffset';
|
||||
operator '.caller' macro LoadCallerFromFrame(f: Frame): Frame {
|
||||
const result: RawPtr = LoadPointerFromFrame(f, kStandardFrameCallerFPOffset);
|
||||
return %RawPointerCast<Frame>(result);
|
||||
}
|
||||
|
||||
type ContextOrFrameType = Context | FrameType;
|
||||
Cast<ContextOrFrameType>(implicit context: Context)(o: Object):
|
||||
ContextOrFrameType
|
||||
labels CastError {
|
||||
typeswitch (o) {
|
||||
case (c: Context): {
|
||||
return c;
|
||||
}
|
||||
case (t: FrameType): {
|
||||
return t;
|
||||
}
|
||||
case (Object): {
|
||||
goto CastError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const kStandardFrameContextOrFrameTypeOffset: constexpr int31
|
||||
generates 'StandardFrameConstants::kContextOrFrameTypeOffset';
|
||||
operator '.context_or_frame_type'
|
||||
macro LoadContextOrFrameTypeFromFrame(implicit context: Context)(f: Frame):
|
||||
ContextOrFrameType {
|
||||
return UnsafeCast<ContextOrFrameType>(
|
||||
LoadObjectFromFrame(f, kStandardFrameContextOrFrameTypeOffset));
|
||||
}
|
||||
|
||||
const kArgumentsAdaptorFrameLengthOffset: constexpr int31
|
||||
generates 'ArgumentsAdaptorFrameConstants::kLengthOffset';
|
||||
operator '.length'
|
||||
macro LoadLengthFromAdapterFrame(implicit context: Context)(
|
||||
f: ArgumentsAdapterFrame): Smi {
|
||||
return LoadSmiFromFrame(f, kArgumentsAdaptorFrameLengthOffset);
|
||||
}
|
||||
|
||||
operator '==' macro FrameTypeEquals(f1: FrameType, f2: FrameType): bool {
|
||||
return WordEqual(f1, f2);
|
||||
}
|
||||
|
||||
macro Cast<A: type>(implicit context: Context)(o: Frame): A labels CastError;
|
||||
Cast<StandardFrame>(implicit context: Context)(f: Frame):
|
||||
StandardFrame labels CastError {
|
||||
const o: HeapObject =
|
||||
Cast<HeapObject>(f.context_or_frame_type) otherwise CastError;
|
||||
// StandardFrames (which include interpreted and JIT-compiled frames),
|
||||
// unlike other frame types, don't have their own type marker stored in
|
||||
// the frame, but rather have the function's context stored where the
|
||||
// type marker is stored for other frame types. From Torque, it would
|
||||
// be quite expensive to do the test required to distinguish interpreter
|
||||
// frames from JITted ones (and other StandardFrame types), so
|
||||
// StandardFrame is the level of granularity support when iterating the
|
||||
// stack from generated code.
|
||||
// See the descriptions and frame layouts in src/frame-constants.h.
|
||||
if (IsContext(o)) {
|
||||
return %RawPointerCast<StandardFrame>(f);
|
||||
}
|
||||
goto CastError;
|
||||
}
|
||||
|
||||
Cast<ArgumentsAdapterFrame>(implicit context: Context)(f: Frame):
|
||||
ArgumentsAdapterFrame labels CastError {
|
||||
const t: FrameType =
|
||||
Cast<FrameType>(f.context_or_frame_type) otherwise CastError;
|
||||
if (t == ARGUMENTS_ADAPTOR_FRAME) {
|
||||
return %RawPointerCast<ArgumentsAdapterFrame>(f);
|
||||
}
|
||||
goto CastError;
|
||||
}
|
||||
|
||||
// Load target function from the current JS frame.
|
||||
// This is an alternative way of getting the target function in addition to
|
||||
// Parameter(Descriptor::kJSTarget). The latter should be used near the
|
||||
// beginning of builtin code while the target value is still in the register
|
||||
// and the former should be used in slow paths in order to reduce register
|
||||
// pressure on the fast path.
|
||||
macro LoadTargetFromFrame(): JSFunction {
|
||||
return LoadFramePointer().function;
|
||||
}
|
@ -146,7 +146,7 @@ namespace typed_array {
|
||||
|
||||
// TODO(szuend): Check if a more involved thirdIndex calculation is
|
||||
// worth it for very large arrays.
|
||||
const thirdIndex: Smi = from + ((to - from) >>> 1);
|
||||
const thirdIndex: Smi = from + ((to - from) >> 1);
|
||||
|
||||
if (IsDetachedBuffer(array.buffer)) goto Detached;
|
||||
|
||||
|
@ -1307,22 +1307,11 @@ void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true,
|
||||
}
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::LoadFromFrame(int offset, MachineType rep) {
|
||||
Node* frame_pointer = LoadFramePointer();
|
||||
return Load(rep, frame_pointer, IntPtrConstant(offset));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::LoadFromParentFrame(int offset, MachineType rep) {
|
||||
Node* frame_pointer = LoadParentFramePointer();
|
||||
return Load(rep, frame_pointer, IntPtrConstant(offset));
|
||||
}
|
||||
|
||||
TNode<JSFunction> CodeStubAssembler::LoadTargetFromFrame() {
|
||||
DCHECK(IsJSFunctionCall());
|
||||
return CAST(LoadFromFrame(StandardFrameConstants::kFunctionOffset,
|
||||
MachineType::TaggedPointer()));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::LoadBufferObject(Node* buffer, int offset,
|
||||
MachineType rep) {
|
||||
return Load(rep, buffer, IntPtrConstant(offset));
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "src/objects.h"
|
||||
#include "src/objects/arguments.h"
|
||||
#include "src/objects/bigint.h"
|
||||
#include "src/objects/shared-function-info.h"
|
||||
#include "src/objects/smi.h"
|
||||
#include "src/roots.h"
|
||||
|
||||
@ -352,6 +353,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
SmiAboveOrEqual)
|
||||
#undef PARAMETER_BINOP
|
||||
|
||||
uintptr_t ConstexprUintPtrShl(uintptr_t a, int32_t b) { return a << b; }
|
||||
uintptr_t ConstexprUintPtrShr(uintptr_t a, int32_t b) { return a >> b; }
|
||||
|
||||
TNode<Object> NoContextConstant();
|
||||
|
||||
#define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \
|
||||
@ -460,6 +464,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
BitcastTaggedToWord(SmiConstant(-1))));
|
||||
}
|
||||
|
||||
TNode<Smi> SmiSar(TNode<Smi> a, int shift) {
|
||||
return BitcastWordToTaggedSigned(
|
||||
WordAnd(WordSar(BitcastTaggedToWord(a), shift),
|
||||
BitcastTaggedToWord(SmiConstant(-1))));
|
||||
}
|
||||
|
||||
Node* WordOrSmiShl(Node* a, int shift, ParameterMode mode) {
|
||||
if (mode == SMI_PARAMETERS) {
|
||||
return SmiShl(CAST(a), shift);
|
||||
@ -713,23 +723,20 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// Branches to {if_true} when Debug::ExecutionMode is DebugInfo::kSideEffect.
|
||||
void GotoIfDebugExecutionModeChecksSideEffects(Label* if_true);
|
||||
|
||||
// Load value from current frame by given offset in bytes.
|
||||
Node* LoadFromFrame(int offset, MachineType rep = MachineType::AnyTagged());
|
||||
// Load value from current parent frame by given offset in bytes.
|
||||
Node* LoadFromParentFrame(int offset,
|
||||
MachineType rep = MachineType::AnyTagged());
|
||||
|
||||
// Load target function from the current JS frame.
|
||||
// This is an alternative way of getting the target function in addition to
|
||||
// Parameter(Descriptor::kJSTarget). The latter should be used near the
|
||||
// beginning of builtin code while the target value is still in the register
|
||||
// and the former should be used in slow paths in order to reduce register
|
||||
// pressure on the fast path.
|
||||
TNode<JSFunction> LoadTargetFromFrame();
|
||||
|
||||
// Load an object pointer from a buffer that isn't in the heap.
|
||||
Node* LoadBufferObject(Node* buffer, int offset,
|
||||
MachineType rep = MachineType::AnyTagged());
|
||||
TNode<RawPtrT> LoadBufferPointer(TNode<RawPtrT> buffer, int offset) {
|
||||
return UncheckedCast<RawPtrT>(
|
||||
LoadBufferObject(buffer, offset, MachineType::Pointer()));
|
||||
}
|
||||
TNode<Smi> LoadBufferSmi(TNode<RawPtrT> buffer, int offset) {
|
||||
return CAST(LoadBufferObject(buffer, offset, MachineType::TaggedSigned()));
|
||||
}
|
||||
// Load a field from an object on the heap.
|
||||
Node* LoadObjectField(SloppyTNode<HeapObject> object, int offset,
|
||||
MachineType rep);
|
||||
@ -1129,6 +1136,19 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
return LoadObjectField(function, JSFunction::kPrototypeOrInitialMapOffset);
|
||||
}
|
||||
|
||||
TNode<SharedFunctionInfo> LoadJSFunctionSharedFunctionInfo(
|
||||
TNode<JSFunction> function) {
|
||||
return CAST(
|
||||
LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset));
|
||||
}
|
||||
|
||||
TNode<Int32T> LoadSharedFunctionInfoFormalParameterCount(
|
||||
TNode<SharedFunctionInfo> function) {
|
||||
return TNode<Int32T>::UncheckedCast(LoadObjectField(
|
||||
function, SharedFunctionInfo::kFormalParameterCountOffset,
|
||||
MachineType::Uint16()));
|
||||
}
|
||||
|
||||
void StoreObjectByteNoWriteBarrier(TNode<HeapObject> object, int offset,
|
||||
TNode<Word32T> value);
|
||||
|
||||
|
@ -71,8 +71,8 @@ class CommonFrameConstants : public AllStatic {
|
||||
-(kCPSlotSize + kContextOrFrameTypeSize);
|
||||
};
|
||||
|
||||
// StandardFrames are used for interpreted, full-codegen and optimized
|
||||
// JavaScript frames. They always have a context below the saved fp/constant
|
||||
// StandardFrames are used for interpreted and optimized JavaScript
|
||||
// frames. They always have a context below the saved fp/constant
|
||||
// pool and below that the JSFunction of the executing function.
|
||||
//
|
||||
// slot JS frame
|
||||
|
@ -226,6 +226,8 @@ void CSAGenerator::EmitInstruction(const CallIntrinsicInstruction& instruction,
|
||||
"String or Number");
|
||||
} else if (return_type->IsSubtypeOf(TypeOracle::GetIntPtrType())) {
|
||||
out_ << "ca_.IntPtrConstant";
|
||||
} else if (return_type->IsSubtypeOf(TypeOracle::GetUIntPtrType())) {
|
||||
out_ << "ca_.UintPtrConstant";
|
||||
} else if (return_type->IsSubtypeOf(TypeOracle::GetInt32Type())) {
|
||||
out_ << "ca_.Int32Constant";
|
||||
} else {
|
||||
|
@ -1808,6 +1808,12 @@ VisitResult ImplementationVisitor::GenerateCall(
|
||||
"%RawConstexprCast must take a single parameter with constexpr "
|
||||
"type");
|
||||
}
|
||||
if (!return_type->IsConstexpr()) {
|
||||
std::stringstream s;
|
||||
s << *return_type
|
||||
<< " return type for %RawConstexprCast is not constexpr";
|
||||
ReportError(s.str());
|
||||
}
|
||||
std::stringstream result;
|
||||
result << "static_cast<" << return_type->GetGeneratedTypeName() << ">(";
|
||||
result << constexpr_arguments[0];
|
||||
|
@ -124,6 +124,10 @@ class TypeOracle : public ContextualClass<TypeOracle> {
|
||||
return Get().GetBuiltinType(INTPTR_TYPE_STRING);
|
||||
}
|
||||
|
||||
static const Type* GetUIntPtrType() {
|
||||
return Get().GetBuiltinType(UINTPTR_TYPE_STRING);
|
||||
}
|
||||
|
||||
static const Type* GetInt32Type() {
|
||||
return Get().GetBuiltinType(INT32_TYPE_STRING);
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ static const char* const STRING_TYPE_STRING = "String";
|
||||
static const char* const NUMBER_TYPE_STRING = "Number";
|
||||
static const char* const CODE_TYPE_STRING = "Code";
|
||||
static const char* const INTPTR_TYPE_STRING = "intptr";
|
||||
static const char* const UINTPTR_TYPE_STRING = "uintptr";
|
||||
static const char* const INT32_TYPE_STRING = "int32";
|
||||
static const char* const CONST_INT31_TYPE_STRING = "constexpr int31";
|
||||
static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
|
||||
|
@ -375,6 +375,22 @@ TEST(TestLookup) {
|
||||
ft.Call();
|
||||
}
|
||||
|
||||
TEST(TestFrame1) {
|
||||
CcTest::InitializeVM();
|
||||
Isolate* isolate(CcTest::i_isolate());
|
||||
i::HandleScope scope(isolate);
|
||||
Handle<Context> context =
|
||||
Utils::OpenHandle(*v8::Isolate::GetCurrent()->GetCurrentContext());
|
||||
CodeAssemblerTester asm_tester(isolate);
|
||||
TestTorqueAssembler m(asm_tester.state());
|
||||
{
|
||||
m.TestFrame1(m.UncheckedCast<Context>(m.HeapConstant(context)));
|
||||
m.Return(m.UndefinedConstant());
|
||||
}
|
||||
FunctionTester ft(asm_tester.GenerateCode(), 0);
|
||||
ft.Call();
|
||||
}
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -670,4 +670,23 @@ namespace test {
|
||||
}
|
||||
label Fail {}
|
||||
}
|
||||
|
||||
macro TestFrame1(implicit context: Context)() {
|
||||
const f: Frame = LoadFramePointer();
|
||||
const frameType: FrameType =
|
||||
Cast<FrameType>(f.context_or_frame_type) otherwise unreachable;
|
||||
assert(frameType == STUB_FRAME);
|
||||
assert(f.caller == LoadParentFramePointer());
|
||||
typeswitch (f) {
|
||||
case (f: StandardFrame): {
|
||||
unreachable;
|
||||
}
|
||||
case (f: ArgumentsAdapterFrame): {
|
||||
unreachable;
|
||||
}
|
||||
case (f: StubFrame): {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
8
third_party/v8/builtins/array-sort.tq
vendored
8
third_party/v8/builtins/array-sort.tq
vendored
@ -676,7 +676,7 @@ namespace array {
|
||||
|
||||
// Find pivot insertion point.
|
||||
while (left < right) {
|
||||
const mid: Smi = left + ((right - left) >>> 1);
|
||||
const mid: Smi = left + ((right - left) >> 1);
|
||||
const midElement: Object =
|
||||
CallLoad(context, sortState, load, elements, mid)
|
||||
otherwise Bailout;
|
||||
@ -999,7 +999,7 @@ namespace array {
|
||||
// a[base + lastOfs - 1] < key <= a[base + offset].
|
||||
lastOfs++;
|
||||
while (lastOfs < offset) {
|
||||
const m: Smi = lastOfs + ((offset - lastOfs) >>> 1);
|
||||
const m: Smi = lastOfs + ((offset - lastOfs) >> 1);
|
||||
|
||||
const baseMElement: Object = CallLoad(
|
||||
context, sortState, load,
|
||||
@ -1120,7 +1120,7 @@ namespace array {
|
||||
// a[base + lastOfs - 1] < key <= a[base + ofs].
|
||||
lastOfs++;
|
||||
while (lastOfs < offset) {
|
||||
const m: Smi = lastOfs + ((offset - lastOfs) >>> 1);
|
||||
const m: Smi = lastOfs + ((offset - lastOfs) >> 1);
|
||||
|
||||
const baseMElement: Object = CallLoad(
|
||||
context, sortState, load,
|
||||
@ -1531,7 +1531,7 @@ namespace array {
|
||||
assert(n >= 0);
|
||||
while (n >= 64) {
|
||||
r = r | (n & 1);
|
||||
n = n >>> 1;
|
||||
n = n >> 1;
|
||||
}
|
||||
|
||||
const minRunLength: Smi = n + r;
|
||||
|
Loading…
Reference in New Issue
Block a user