MIPS: Handlify CompileConstructStub and the remaining CallStubCompiler functions.

Port r9837 (38061af).
Port r9834 (95ac04).

Original commit message (r9834):
Also, handlify functions for loading with interceptors and callbacks.
Remove some unneeded code.  Rename Foreign::address() because it
confusingly shadows HeapObject::address() which does something quite
different.

BUG=
TEST=

Review URL: http://codereview.chromium.org/8400087
Patch from Gergely Kis <gergely@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9844 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3ba06319
......@@ -5351,7 +5351,8 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
void StringCharCodeAtGenerator::GenerateSlow(
MacroAssembler* masm, const RuntimeCallHelper& call_helper) {
MacroAssembler* masm,
const RuntimeCallHelper& call_helper) {
__ Abort("Unexpected fallthrough to CharCodeAt slow case");
// Index is not a smi.
......@@ -5437,7 +5438,8 @@ void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
void StringCharFromCodeGenerator::GenerateSlow(
MacroAssembler* masm, const RuntimeCallHelper& call_helper) {
MacroAssembler* masm,
const RuntimeCallHelper& call_helper) {
__ Abort("Unexpected fallthrough to CharFromCode slow case");
__ bind(&slow_case_);
......@@ -5463,7 +5465,8 @@ void StringCharAtGenerator::GenerateFast(MacroAssembler* masm) {
void StringCharAtGenerator::GenerateSlow(
MacroAssembler* masm, const RuntimeCallHelper& call_helper) {
MacroAssembler* masm,
const RuntimeCallHelper& call_helper) {
char_code_at_generator_.GenerateSlow(masm, call_helper);
char_from_code_generator_.GenerateSlow(masm, call_helper);
}
......@@ -7021,86 +7024,6 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
}
// TODO(kmillikin): Eliminate this function when the stub cache is fully
// handlified.
MaybeObject* StringDictionaryLookupStub::TryGenerateNegativeLookup(
MacroAssembler* masm,
Label* miss,
Label* done,
Register receiver,
Register properties,
String* name,
Register scratch0) {
// If names of slots in range from 1 to kProbes - 1 for the hash value are
// not equal to the name and kProbes-th slot is not used (its name is the
// undefined value), it guarantees the hash table doesn't contain the
// property. It's true even if some slots represent deleted properties
// (their names are the null value).
for (int i = 0; i < kInlinedProbes; i++) {
// scratch0 points to properties hash.
// Compute the masked index: (hash + i + i * i) & mask.
Register index = scratch0;
// Capacity is smi 2^n.
__ lw(index, FieldMemOperand(properties, kCapacityOffset));
__ Subu(index, index, Operand(1));
__ And(index, index, Operand(
Smi::FromInt(name->Hash() + StringDictionary::GetProbeOffset(i))));
// Scale the index by multiplying by the entry size.
ASSERT(StringDictionary::kEntrySize == 3);
// index *= 3.
__ sll(at, index, 1);
__ Addu(index, index, at);
Register entity_name = scratch0;
// Having undefined at this place means the name is not contained.
ASSERT_EQ(kSmiTagSize, 1);
Register tmp = properties;
__ sll(scratch0, index, 1);
__ Addu(tmp, properties, scratch0);
__ lw(entity_name, FieldMemOperand(tmp, kElementsStartOffset));
ASSERT(!tmp.is(entity_name));
__ LoadRoot(tmp, Heap::kUndefinedValueRootIndex);
__ Branch(done, eq, entity_name, Operand(tmp));
if (i != kInlinedProbes - 1) {
// Stop if found the property.
__ Branch(miss, eq, entity_name, Operand(Handle<String>(name)));
// Check if the entry name is not a symbol.
__ lw(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset));
__ lbu(entity_name,
FieldMemOperand(entity_name, Map::kInstanceTypeOffset));
__ And(scratch0, entity_name, Operand(kIsSymbolMask));
__ Branch(miss, eq, scratch0, Operand(zero_reg));
// Restore the properties.
__ lw(properties,
FieldMemOperand(receiver, JSObject::kPropertiesOffset));
}
}
const int spill_mask =
(ra.bit() | t2.bit() | t1.bit() | t0.bit() | a3.bit() |
a2.bit() | a1.bit() | a0.bit() | v0.bit());
__ MultiPush(spill_mask);
__ lw(a0, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
__ li(a1, Operand(Handle<String>(name)));
StringDictionaryLookupStub stub(NEGATIVE_LOOKUP);
MaybeObject* result = masm->TryCallStub(&stub);
if (result->IsFailure()) return result;
__ mov(at, v0);
__ MultiPop(spill_mask);
__ Branch(done, eq, at, Operand(zero_reg));
__ Branch(miss, ne, at, Operand(zero_reg));
return result;
}
// Probe the string dictionary in the |elements| register. Jump to the
// |done| label if a property with the given name is found. Jump to
// the |miss| label otherwise.
......
......@@ -807,17 +807,6 @@ class StringDictionaryLookupStub: public CodeStub {
Handle<String> name,
Register scratch0);
// TODO(kmillikin): Eliminate this function when the stub cache is fully
// handlified.
MUST_USE_RESULT static MaybeObject* TryGenerateNegativeLookup(
MacroAssembler* masm,
Label* miss,
Label* done,
Register receiver,
Register properties,
String* name,
Register scratch0);
static void GeneratePositiveLookup(MacroAssembler* masm,
Label* miss,
Label* done,
......
......@@ -3610,7 +3610,7 @@ void MacroAssembler::InvokeFunction(Register function,
}
void MacroAssembler::InvokeFunction(JSFunction* function,
void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
const ParameterCount& actual,
InvokeFlag flag,
CallKind call_kind) {
......@@ -3618,7 +3618,7 @@ void MacroAssembler::InvokeFunction(JSFunction* function,
ASSERT(flag == JUMP_FUNCTION || has_frame());
// Get the function and setup the context.
li(a1, Operand(Handle<JSFunction>(function)));
li(a1, Operand(function));
lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
ParameterCount expected(function->shared()->formal_parameter_count());
......@@ -3739,45 +3739,19 @@ void MacroAssembler::CallStub(CodeStub* stub, Condition cond,
}
MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub, Condition cond,
Register r1, const Operand& r2) {
ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
Object* result;
{ MaybeObject* maybe_result = stub->TryGetCode();
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET,
kNoASTId, cond, r1, r2);
return result;
}
void MacroAssembler::TailCallStub(CodeStub* stub) {
ASSERT(allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe());
Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
}
MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub,
Condition cond,
Register r1,
const Operand& r2) {
Object* result;
{ MaybeObject* maybe_result = stub->TryGetCode();
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Jump(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET, cond, r1, r2);
return result;
}
static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
return ref0.address() - ref1.address();
}
MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(
ExternalReference function, int stack_space) {
void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
int stack_space) {
ExternalReference next_address =
ExternalReference::handle_scope_next_address();
const int kNextOffset = 0;
......@@ -3848,11 +3822,10 @@ MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(
Ret();
bind(&promote_scheduled_exception);
MaybeObject* result = TryTailCallExternalReference(
ExternalReference(Runtime::kPromoteScheduledException, isolate()), 0, 1);
if (result->IsFailure()) {
return result;
}
TailCallExternalReference(
ExternalReference(Runtime::kPromoteScheduledException, isolate()),
0,
1);
// HandleScope limit has changed. Delete allocated extensions.
bind(&delete_allocated_handles);
......@@ -3865,8 +3838,6 @@ MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(
1);
mov(v0, s0);
jmp(&leave_exit_frame);
return result;
}
......@@ -4089,17 +4060,6 @@ void MacroAssembler::TailCallExternalReference(const ExternalReference& ext,
}
MaybeObject* MacroAssembler::TryTailCallExternalReference(
const ExternalReference& ext, int num_arguments, int result_size) {
// TODO(1236192): Most runtime routines don't need the number of
// arguments passed in because it is constant. At some point we
// should remove this need and make the runtime routine entry code
// smarter.
li(a0, num_arguments);
return TryJumpToExternalReference(ext);
}
void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
int num_arguments,
int result_size) {
......@@ -4116,14 +4076,6 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
}
MaybeObject* MacroAssembler::TryJumpToExternalReference(
const ExternalReference& builtin) {
li(a1, Operand(builtin));
CEntryStub stub(1);
return TryTailCallStub(&stub);
}
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
const CallWrapper& call_wrapper) {
......
......@@ -812,7 +812,7 @@ class MacroAssembler: public Assembler {
const CallWrapper& call_wrapper,
CallKind call_kind);
void InvokeFunction(JSFunction* function,
void InvokeFunction(Handle<JSFunction> function,
const ParameterCount& actual,
InvokeFlag flag,
CallKind call_kind);
......@@ -1042,27 +1042,9 @@ class MacroAssembler: public Assembler {
void CallStub(CodeStub* stub, Condition cond = cc_always,
Register r1 = zero_reg, const Operand& r2 = Operand(zero_reg));
// Call a code stub and return the code object called. Try to generate
// the code if necessary. Do not perform a GC but instead return a retry
// after GC failure.
MUST_USE_RESULT MaybeObject* TryCallStub(CodeStub* stub,
Condition cond = cc_always,
Register r1 = zero_reg,
const Operand& r2 =
Operand(zero_reg));
// Tail call a code stub (jump).
void TailCallStub(CodeStub* stub);
// Tail call a code stub (jump) and return the code object called. Try to
// generate the code if necessary. Do not perform a GC but instead return
// a retry after GC failure.
MUST_USE_RESULT MaybeObject* TryTailCallStub(CodeStub* stub,
Condition cond = cc_always,
Register r1 = zero_reg,
const Operand& r2 =
Operand(zero_reg));
void CallJSExitStub(CodeStub* stub);
// Call a runtime routine.
......@@ -1083,12 +1065,6 @@ class MacroAssembler: public Assembler {
int num_arguments,
int result_size);
// Tail call of a runtime routine (jump). Try to generate the code if
// necessary. Do not perform a GC but instead return a retry after GC
// failure.
MUST_USE_RESULT MaybeObject* TryTailCallExternalReference(
const ExternalReference& ext, int num_arguments, int result_size);
// Convenience function: tail call a runtime routine (jump).
void TailCallRuntime(Runtime::FunctionId fid,
int num_arguments,
......@@ -1139,16 +1115,15 @@ class MacroAssembler: public Assembler {
void SetCallCDoubleArguments(DoubleRegister dreg1, DoubleRegister dreg2);
void SetCallCDoubleArguments(DoubleRegister dreg, Register reg);
// Calls an API function. Allocates HandleScope, extracts returned value
// from handle and propagates exceptions. Restores context.
MaybeObject* TryCallApiFunctionAndReturn(ExternalReference function,
int stack_space);
// Calls an API function. Allocates HandleScope, extracts returned value
// from handle and propagates exceptions. Restores context. stack_space
// - space to be unwound on exit (includes the call js arguments space and
// the additional space allocated for the fast call).
void CallApiFunctionAndReturn(ExternalReference function, int stack_space);
// Jump to the builtin routine.
void JumpToExternalReference(const ExternalReference& builtin);
MaybeObject* TryJumpToExternalReference(const ExternalReference& ext);
// Invoke specified builtin JavaScript function. Adds an entry to
// the unresolved list if the name does not resolve.
void InvokeBuiltin(Builtins::JavaScript id,
......
This diff is collapsed.
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