Unified CallWrapper and PostCallGenerator classes, the former is a

generalization of the latter. This makes CallWrapper architecture-independant,
so it can be pulled up into assembler.h, nuking 3 copy-n-paste classes. Only a
small improvement, but nevertheless...
Review URL: http://codereview.chromium.org/6893156

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7758 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3e94ac95
......@@ -33,9 +33,6 @@
namespace v8 {
namespace internal {
// Forward declaration.
class CallWrapper;
// ----------------------------------------------------------------------------
// Static helper functions
......@@ -1066,21 +1063,6 @@ class CodePatcher {
#endif // ENABLE_DEBUGGER_SUPPORT
// Helper class for generating code or data associated with the code
// right after a call instruction. As an example this can be used to
// generate safepoint data after calls for crankshaft.
class CallWrapper {
public:
CallWrapper() { }
virtual ~CallWrapper() { }
// Called just before emitting a call. Argument is the size of the generated
// call code.
virtual void BeforeCall(int call_size) = 0;
// Called just after emitting a call, i.e., at the return site for the call.
virtual void AfterCall() = 0;
};
// -----------------------------------------------------------------------------
// Static helper functions.
......
......@@ -843,6 +843,20 @@ static inline int NumberOfBitsSet(uint32_t x) {
double power_double_int(double x, int y);
double power_double_double(double x, double y);
// Helper class for generating code or data associated with the code
// right after a call instruction. As an example this can be used to
// generate safepoint data after calls for crankshaft.
class CallWrapper {
public:
CallWrapper() { }
virtual ~CallWrapper() { }
// Called just before emitting a call. Argument is the size of the generated
// call code.
virtual void BeforeCall(int call_size) = 0;
// Called just after emitting a call, i.e., at the return site for the call.
virtual void AfterCall() = 0;
};
} } // namespace v8::internal
#endif // V8_ASSEMBLER_H_
......@@ -1580,12 +1580,24 @@ void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
}
int Assembler::CallSize(const Operand& adr) {
// Call size is 1 (opcode) + adr.len_ (operand).
return 1 + adr.len_;
}
void Assembler::call(const Operand& adr) {
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
last_pc_ = pc_;
EMIT(0xFF);
emit_operand(edx, adr);
ASSERT(pc_ - last_pc_ == CallSize(adr));
}
int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
}
......
......@@ -847,7 +847,9 @@ class Assembler : public AssemblerBase {
// Calls
void call(Label* L);
void call(byte* entry, RelocInfo::Mode rmode);
int CallSize(const Operand& adr);
void call(const Operand& adr);
int CallSize(Handle<Code> code, RelocInfo::Mode mode);
void call(Handle<Code> code,
RelocInfo::Mode rmode,
unsigned ast_id = kNoASTId);
......
......@@ -40,7 +40,7 @@ namespace internal {
// When invoking builtins, we need to record the safepoint in the middle of
// the invoke instruction sequence generated by the macro assembler.
class SafepointGenerator : public PostCallGenerator {
class SafepointGenerator : public CallWrapper {
public:
SafepointGenerator(LCodeGen* codegen,
LPointerMap* pointers,
......@@ -50,7 +50,9 @@ class SafepointGenerator : public PostCallGenerator {
deoptimization_index_(deoptimization_index) {}
virtual ~SafepointGenerator() { }
virtual void Generate() {
virtual void BeforeCall(int call_size) {}
virtual void AfterCall() {
codegen_->RecordSafepoint(pointers_, deoptimization_index_);
}
......
......@@ -1435,7 +1435,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
const Operand& code_operand,
NearLabel* done,
InvokeFlag flag,
PostCallGenerator* post_call_generator) {
CallWrapper* call_wrapper) {
bool definitely_matches = false;
Label invoke;
if (expected.is_immediate()) {
......@@ -1485,8 +1485,11 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
}
if (flag == CALL_FUNCTION) {
if (call_wrapper != NULL) {
call_wrapper->BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
}
call(adaptor, RelocInfo::CODE_TARGET);
if (post_call_generator != NULL) post_call_generator->Generate();
if (call_wrapper != NULL) call_wrapper->AfterCall();
jmp(done);
} else {
jmp(adaptor, RelocInfo::CODE_TARGET);
......@@ -1500,13 +1503,14 @@ void MacroAssembler::InvokeCode(const Operand& code,
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
PostCallGenerator* post_call_generator) {
CallWrapper* call_wrapper) {
NearLabel done;
InvokePrologue(expected, actual, Handle<Code>::null(), code,
&done, flag, post_call_generator);
&done, flag, call_wrapper);
if (flag == CALL_FUNCTION) {
if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code));
call(code);
if (post_call_generator != NULL) post_call_generator->Generate();
if (call_wrapper != NULL) call_wrapper->AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
jmp(code);
......@@ -1520,14 +1524,14 @@ void MacroAssembler::InvokeCode(Handle<Code> code,
const ParameterCount& actual,
RelocInfo::Mode rmode,
InvokeFlag flag,
PostCallGenerator* post_call_generator) {
CallWrapper* call_wrapper) {
NearLabel done;
Operand dummy(eax);
InvokePrologue(expected, actual, code, dummy, &done,
flag, post_call_generator);
InvokePrologue(expected, actual, code, dummy, &done, flag, call_wrapper);
if (flag == CALL_FUNCTION) {
if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code, rmode));
call(code, rmode);
if (post_call_generator != NULL) post_call_generator->Generate();
if (call_wrapper != NULL) call_wrapper->AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
jmp(code, rmode);
......@@ -1539,7 +1543,7 @@ void MacroAssembler::InvokeCode(Handle<Code> code,
void MacroAssembler::InvokeFunction(Register fun,
const ParameterCount& actual,
InvokeFlag flag,
PostCallGenerator* post_call_generator) {
CallWrapper* call_wrapper) {
ASSERT(fun.is(edi));
mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
......@@ -1548,14 +1552,14 @@ void MacroAssembler::InvokeFunction(Register fun,
ParameterCount expected(ebx);
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
expected, actual, flag, post_call_generator);
expected, actual, flag, call_wrapper);
}
void MacroAssembler::InvokeFunction(JSFunction* function,
const ParameterCount& actual,
InvokeFlag flag,
PostCallGenerator* post_call_generator) {
CallWrapper* call_wrapper) {
ASSERT(function->is_compiled());
// Get the function and setup the context.
mov(edi, Immediate(Handle<JSFunction>(function)));
......@@ -1567,18 +1571,18 @@ void MacroAssembler::InvokeFunction(JSFunction* function,
// code field in the function to allow recompilation to take effect
// without changing any of the call sites.
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
expected, actual, flag, post_call_generator);
expected, actual, flag, call_wrapper);
} else {
Handle<Code> code(function->code());
InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET,
flag, post_call_generator);
flag, call_wrapper);
}
}
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
PostCallGenerator* post_call_generator) {
CallWrapper* call_wrapper) {
// Calls are not allowed in some stubs.
ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
......@@ -1588,7 +1592,7 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
ParameterCount expected(0);
GetBuiltinFunction(edi, id);
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
expected, expected, flag, post_call_generator);
expected, expected, flag, call_wrapper);
}
void MacroAssembler::GetBuiltinFunction(Register target,
......
......@@ -49,9 +49,6 @@ enum AllocationFlags {
// distinguish memory operands from other operands on ia32.
typedef Operand MemOperand;
// Forward declaration.
class PostCallGenerator;
// MacroAssembler implements a collection of frequently used macros.
class MacroAssembler: public Assembler {
public:
......@@ -160,32 +157,32 @@ class MacroAssembler: public Assembler {
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
CallWrapper* call_wrapper = NULL);
void InvokeCode(Handle<Code> code,
const ParameterCount& expected,
const ParameterCount& actual,
RelocInfo::Mode rmode,
InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
CallWrapper* call_wrapper = NULL);
// Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking.
void InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
CallWrapper* call_wrapper = NULL);
void InvokeFunction(JSFunction* function,
const ParameterCount& actual,
InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
CallWrapper* call_wrapper = NULL);
// Invoke specified builtin JavaScript function. Adds an entry to
// the unresolved list if the name does not resolve.
void InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
CallWrapper* call_wrapper = NULL);
// Store the function for the given builtin in the target register.
void GetBuiltinFunction(Register target, Builtins::JavaScript id);
......@@ -652,7 +649,7 @@ class MacroAssembler: public Assembler {
const Operand& code_operand,
NearLabel* done,
InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
CallWrapper* call_wrapper = NULL);
// Activation support.
void EnterFrame(StackFrame::Type type);
......@@ -734,17 +731,6 @@ class CodePatcher {
};
// Helper class for generating code or data associated with the code
// right after a call instruction. As an example this can be used to
// generate safepoint data after calls for crankshaft.
class PostCallGenerator {
public:
PostCallGenerator() { }
virtual ~PostCallGenerator() { }
virtual void Generate() = 0;
};
// -----------------------------------------------------------------------------
// Static helper functions.
......
......@@ -1658,6 +1658,18 @@ void MacroAssembler::Jump(const Operand& target,
}
int MacroAssembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
UNIMPLEMENTED_MIPS();
return 0;
}
int MacroAssembler::CallSize(Register reg) {
UNIMPLEMENTED_MIPS();
return 0;
}
// Note: To call gcc-compiled C code on mips, you must call thru t9.
void MacroAssembler::Call(const Operand& target, BranchDelaySlot bdslot) {
BlockTrampolinePoolScope block_trampoline_pool(this);
......@@ -2243,7 +2255,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
Register code_reg,
Label* done,
InvokeFlag flag,
PostCallGenerator* post_call_generator) {
CallWrapper* call_wrapper) {
bool definitely_matches = false;
Label regular_invoke;
......@@ -2296,8 +2308,11 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
Handle<Code> adaptor =
isolate()->builtins()->ArgumentsAdaptorTrampoline();
if (flag == CALL_FUNCTION) {
if (call_wrapper != NULL) {
call_wrapper->BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
}
Call(adaptor, RelocInfo::CODE_TARGET);
if (post_call_generator != NULL) post_call_generator->Generate();
if (call_wrapper != NULL) call_wrapper->AfterCall();
jmp(done);
} else {
Jump(adaptor, RelocInfo::CODE_TARGET);
......@@ -2311,11 +2326,11 @@ void MacroAssembler::InvokeCode(Register code,
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
PostCallGenerator* post_call_generator) {
CallWrapper* call_wrapper) {
Label done;
InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag,
post_call_generator);
call_wrapper);
if (flag == CALL_FUNCTION) {
Call(code);
} else {
......@@ -2350,7 +2365,7 @@ void MacroAssembler::InvokeCode(Handle<Code> code,
void MacroAssembler::InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
PostCallGenerator* post_call_generator) {
CallWrapper* call_wrapper) {
// Contract with called JS functions requires that function is passed in a1.
ASSERT(function.is(a1));
Register expected_reg = a2;
......@@ -2365,7 +2380,7 @@ void MacroAssembler::InvokeFunction(Register function,
lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
ParameterCount expected(expected_reg);
InvokeCode(code_reg, expected, actual, flag, post_call_generator);
InvokeCode(code_reg, expected, actual, flag, call_wrapper);
}
......@@ -2642,11 +2657,12 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
PostCallGenerator* post_call_generator) {
CallWrapper* call_wrapper) {
GetBuiltinEntry(t9, id);
if (flag == CALL_FUNCTION) {
if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(t9));
Call(t9);
if (post_call_generator != NULL) post_call_generator->Generate();
if (call_wrapper != NULL) call_wrapper->AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
Jump(t9);
......
......@@ -36,7 +36,6 @@ namespace internal {
// Forward declaration.
class JumpTarget;
class PostCallGenerator;
// Reserved Register Usage Summary.
//
......@@ -588,7 +587,7 @@ DECLARE_NOTARGET_PROTOTYPE(Ret)
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
CallWrapper* call_wrapper = NULL);
void InvokeCode(Handle<Code> code,
const ParameterCount& expected,
......@@ -601,7 +600,7 @@ DECLARE_NOTARGET_PROTOTYPE(Ret)
void InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
CallWrapper* call_wrapper = NULL);
void InvokeFunction(JSFunction* function,
const ParameterCount& actual,
......@@ -771,7 +770,7 @@ DECLARE_NOTARGET_PROTOTYPE(Ret)
// the unresolved list if the name does not resolve.
void InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
CallWrapper* call_wrapper = NULL);
// Store the code object for the given builtin in the target register and
// setup the function in a1.
......@@ -954,7 +953,7 @@ DECLARE_NOTARGET_PROTOTYPE(Ret)
Register code_reg,
Label* done,
InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
CallWrapper* call_wrapper = NULL);
// Get the code for the given builtin. Returns if able to resolve
// the function in the 'resolved' flag.
......@@ -1007,17 +1006,6 @@ class CodePatcher {
#endif // ENABLE_DEBUGGER_SUPPORT
// Helper class for generating code or data associated with the code
// right after a call instruction. As an example this can be used to
// generate safepoint data after calls for crankshaft.
class PostCallGenerator {
public:
PostCallGenerator() { }
virtual ~PostCallGenerator() { }
virtual void Generate() = 0;
};
// -----------------------------------------------------------------------------
// Static helper functions.
......
......@@ -61,7 +61,6 @@ typedef Operand MemOperand;
// Forward declaration.
class JumpTarget;
class CallWrapper;
struct SmiIndex {
SmiIndex(Register index_register, ScaleFactor scale)
......@@ -1192,21 +1191,6 @@ class CodePatcher {
};
// Helper class for generating code or data associated with the code
// right before or after a call instruction. As an example this can be used to
// generate safepoint data after calls for crankshaft.
class CallWrapper {
public:
CallWrapper() { }
virtual ~CallWrapper() { }
// Called just before emitting a call. Argument is the size of the generated
// call code.
virtual void BeforeCall(int call_size) = 0;
// Called just after emitting a call, i.e., at the return site for the call.
virtual void AfterCall() = 0;
};
// -----------------------------------------------------------------------------
// Static helper functions.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment