| Index: src/x64/ic-x64.cc
|
| ===================================================================
|
| --- src/x64/ic-x64.cc (revision 3935)
|
| +++ src/x64/ic-x64.cc (working copy)
|
| @@ -212,26 +212,40 @@
|
| }
|
|
|
|
|
| -void KeyedLoadIC::Generate(MacroAssembler* masm,
|
| - ExternalReference const& f) {
|
| +void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- rsp[0] : return address
|
| // -- rsp[8] : name
|
| // -- rsp[16] : receiver
|
| // -----------------------------------
|
|
|
| - __ movq(rax, Operand(rsp, kPointerSize));
|
| - __ movq(rcx, Operand(rsp, 2 * kPointerSize));
|
| __ pop(rbx);
|
| - __ push(rcx); // receiver
|
| - __ push(rax); // name
|
| + __ push(Operand(rsp, 1 * kPointerSize)); // receiver
|
| + __ push(Operand(rsp, 1 * kPointerSize)); // name
|
| __ push(rbx); // return address
|
|
|
| // Perform tail call to the entry.
|
| - __ TailCallRuntime(f, 2, 1);
|
| + __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedLoadIC_Miss)), 2, 1);
|
| }
|
|
|
|
|
| +void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
|
| + // ----------- S t a t e -------------
|
| + // -- rsp[0] : return address
|
| + // -- rsp[8] : name
|
| + // -- rsp[16] : receiver
|
| + // -----------------------------------
|
| +
|
| + __ pop(rbx);
|
| + __ push(Operand(rsp, 1 * kPointerSize)); // receiver
|
| + __ push(Operand(rsp, 1 * kPointerSize)); // name
|
| + __ push(rbx); // return address
|
| +
|
| + // Perform tail call to the entry.
|
| + __ TailCallRuntime(ExternalReference(Runtime::kKeyedGetProperty), 2, 1);
|
| +}
|
| +
|
| +
|
| void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- rsp[0] : return address
|
| @@ -301,7 +315,7 @@
|
| // Slow case: Load name and receiver from stack and jump to runtime.
|
| __ bind(&slow);
|
| __ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
|
| - Generate(masm, ExternalReference(Runtime::kKeyedGetProperty));
|
| + GenerateRuntimeGetProperty(masm);
|
| __ bind(&check_string);
|
| // The key is not a smi.
|
| // Is it a string?
|
| @@ -538,21 +552,54 @@
|
| // Slow case: Load name and receiver from stack and jump to runtime.
|
| __ bind(&slow);
|
| __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1);
|
| - Generate(masm, ExternalReference(Runtime::kKeyedGetProperty));
|
| + GenerateRuntimeGetProperty(masm);
|
| }
|
|
|
|
|
| -void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
|
| +void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- rsp[0] : return address
|
| - // -- rsp[8] : name
|
| + // -- rsp[8] : key
|
| // -- rsp[16] : receiver
|
| // -----------------------------------
|
| - Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
|
| + Label slow;
|
| +
|
| + // Load key and receiver.
|
| + __ movq(rax, Operand(rsp, kPointerSize));
|
| + __ movq(rcx, Operand(rsp, 2 * kPointerSize));
|
| +
|
| + // Check that the receiver isn't a smi.
|
| + __ JumpIfSmi(rcx, &slow);
|
| +
|
| + // Check that the key is a smi.
|
| + __ JumpIfNotSmi(rax, &slow);
|
| +
|
| + // Get the map of the receiver.
|
| + __ movq(rdx, FieldOperand(rcx, HeapObject::kMapOffset));
|
| +
|
| + // Check that it has indexed interceptor and access checks
|
| + // are not enabled for this object.
|
| + __ movb(rdx, FieldOperand(rdx, Map::kBitFieldOffset));
|
| + __ andb(rdx, Immediate(kSlowCaseBitFieldMask));
|
| + __ cmpb(rdx, Immediate(1 << Map::kHasIndexedInterceptor));
|
| + __ j(not_zero, &slow);
|
| +
|
| + // Everything is fine, call runtime.
|
| + __ pop(rdx);
|
| + __ push(rcx); // receiver
|
| + __ push(rax); // key
|
| + __ push(rdx); // return address
|
| +
|
| + // Perform tail call to the entry.
|
| + __ TailCallRuntime(ExternalReference(
|
| + IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1);
|
| +
|
| + __ bind(&slow);
|
| + GenerateMiss(masm);
|
| }
|
|
|
|
|
| -void KeyedStoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
|
| +void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- rax : value
|
| // -- rsp[0] : return address
|
| @@ -567,28 +614,26 @@
|
| __ push(rcx); // return address
|
|
|
| // Do tail-call to runtime routine.
|
| - __ TailCallRuntime(f, 3, 1);
|
| + __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedStoreIC_Miss)), 3, 1);
|
| }
|
|
|
|
|
| -void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
| +void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- rax : value
|
| - // -- rcx : transition map
|
| // -- rsp[0] : return address
|
| // -- rsp[8] : key
|
| // -- rsp[16] : receiver
|
| // -----------------------------------
|
|
|
| - __ pop(rbx);
|
| + __ pop(rcx);
|
| __ push(Operand(rsp, 1 * kPointerSize)); // receiver
|
| - __ push(rcx); // transition map
|
| + __ push(Operand(rsp, 1 * kPointerSize)); // key
|
| __ push(rax); // value
|
| - __ push(rbx); // return address
|
| + __ push(rcx); // return address
|
|
|
| // Do tail-call to runtime routine.
|
| - __ TailCallRuntime(
|
| - ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
|
| + __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
|
| }
|
|
|
|
|
| @@ -642,7 +687,7 @@
|
|
|
| // Slow case: call runtime.
|
| __ bind(&slow);
|
| - Generate(masm, ExternalReference(Runtime::kSetProperty));
|
| + GenerateRuntimeSetProperty(masm);
|
|
|
| // Check whether the elements is a pixel array.
|
| // rax: value
|
| @@ -906,23 +951,29 @@
|
|
|
| // Slow case: call runtime.
|
| __ bind(&slow);
|
| - Generate(masm, ExternalReference(Runtime::kSetProperty));
|
| + GenerateRuntimeSetProperty(masm);
|
| }
|
|
|
|
|
| void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
|
| + // ----------- S t a t e -------------
|
| + // rcx : function name
|
| + // rsp[0] : return address
|
| + // rsp[8] : argument argc
|
| + // rsp[16] : argument argc - 1
|
| + // ...
|
| + // rsp[argc * 8] : argument 1
|
| + // rsp[(argc + 1) * 8] : argument 0 = receiver
|
| + // -----------------------------------
|
| // Get the receiver of the function from the stack; 1 ~ return address.
|
| __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| - // Get the name of the function to call from the stack.
|
| - // 2 ~ receiver, return address.
|
| - __ movq(rbx, Operand(rsp, (argc + 2) * kPointerSize));
|
|
|
| // Enter an internal frame.
|
| __ EnterInternalFrame();
|
|
|
| // Push the receiver and the name of the function.
|
| __ push(rdx);
|
| - __ push(rbx);
|
| + __ push(rcx);
|
|
|
| // Call the entry.
|
| CEntryStub stub(1);
|
| @@ -960,20 +1011,18 @@
|
|
|
| void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
|
| // ----------- S t a t e -------------
|
| - // rsp[0] return address
|
| - // rsp[8] argument argc
|
| - // rsp[16] argument argc - 1
|
| + // rcx : function name
|
| + // rsp[0] : return address
|
| + // rsp[8] : argument argc
|
| + // rsp[16] : argument argc - 1
|
| // ...
|
| - // rsp[argc * 8] argument 1
|
| - // rsp[(argc + 1) * 8] argument 0 = receiver
|
| - // rsp[(argc + 2) * 8] function name
|
| + // rsp[argc * 8] : argument 1
|
| + // rsp[(argc + 1) * 8] : argument 0 = receiver
|
| // -----------------------------------
|
| Label number, non_number, non_string, boolean, probe, miss;
|
|
|
| // Get the receiver of the function from the stack; 1 ~ return address.
|
| __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| - // Get the name of the function from the stack; 2 ~ return address, receiver
|
| - __ movq(rcx, Operand(rsp, (argc + 2) * kPointerSize));
|
|
|
| // Probe the stub cache.
|
| Code::Flags flags =
|
| @@ -1026,6 +1075,16 @@
|
| int argc,
|
| bool is_global_object,
|
| Label* miss) {
|
| + // ----------- S t a t e -------------
|
| + // rcx : function name
|
| + // rdx : receiver
|
| + // rsp[0] : return address
|
| + // rsp[8] : argument argc
|
| + // rsp[16] : argument argc - 1
|
| + // ...
|
| + // rsp[argc * 8] : argument 1
|
| + // rsp[(argc + 1) * 8] : argument 0 = receiver
|
| + // -----------------------------------
|
| // Search dictionary - put result in register rdx.
|
| GenerateDictionaryLoad(masm, miss, rax, rdx, rbx, rcx, CHECK_DICTIONARY);
|
|
|
| @@ -1052,20 +1111,18 @@
|
|
|
| void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
|
| // ----------- S t a t e -------------
|
| - // rsp[0] return address
|
| - // rsp[8] argument argc
|
| - // rsp[16] argument argc - 1
|
| + // rcx : function name
|
| + // rsp[0] : return address
|
| + // rsp[8] : argument argc
|
| + // rsp[16] : argument argc - 1
|
| // ...
|
| - // rsp[argc * 8] argument 1
|
| - // rsp[(argc + 1) * 8] argument 0 = receiver
|
| - // rsp[(argc + 2) * 8] function name
|
| + // rsp[argc * 8] : argument 1
|
| + // rsp[(argc + 1) * 8] : argument 0 = receiver
|
| // -----------------------------------
|
| Label miss, global_object, non_global_object;
|
|
|
| // Get the receiver of the function from the stack.
|
| __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
|
| - // Get the name of the function from the stack.
|
| - __ movq(rcx, Operand(rsp, (argc + 2) * kPointerSize));
|
|
|
| // Check that the receiver isn't a smi.
|
| __ JumpIfSmi(rdx, &miss);
|
| @@ -1132,22 +1189,20 @@
|
| }
|
|
|
|
|
| -void LoadIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
|
| +void LoadIC::GenerateMiss(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- rcx : name
|
| // -- rsp[0] : return address
|
| // -- rsp[8] : receiver
|
| // -----------------------------------
|
|
|
| - __ movq(rax, Operand(rsp, kPointerSize));
|
| -
|
| __ pop(rbx);
|
| - __ push(rax); // receiver
|
| + __ push(Operand(rsp, 0)); // receiver
|
| __ push(rcx); // name
|
| __ push(rbx); // return address
|
|
|
| // Perform tail call to the entry.
|
| - __ TailCallRuntime(f, 2, 1);
|
| + __ TailCallRuntime(ExternalReference(IC_Utility(kLoadIC_Miss)), 2, 1);
|
| }
|
|
|
|
|
| @@ -1203,17 +1258,6 @@
|
| }
|
|
|
|
|
| -void LoadIC::GenerateMiss(MacroAssembler* masm) {
|
| - // ----------- S t a t e -------------
|
| - // -- rcx : name
|
| - // -- rsp[0] : return address
|
| - // -- rsp[8] : receiver
|
| - // -----------------------------------
|
| -
|
| - Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
|
| -}
|
| -
|
| -
|
| void LoadIC::GenerateNormal(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- rcx : name
|
| @@ -1256,7 +1300,7 @@
|
| // Cache miss: Restore receiver from stack and jump to runtime.
|
| __ bind(&miss);
|
| __ movq(rax, Operand(rsp, 1 * kPointerSize));
|
| - Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
|
| + GenerateMiss(masm);
|
| }
|
|
|
|
|
| @@ -1270,13 +1314,12 @@
|
|
|
| __ movq(rax, Operand(rsp, kPointerSize));
|
|
|
| - StubCompiler::GenerateLoadStringLength(masm, rax, rdx, &miss);
|
| + StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss);
|
| __ bind(&miss);
|
| StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
|
| }
|
|
|
|
|
| -
|
| bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
|
| // The address of the instruction following the call.
|
| Address test_instruction_address =
|
| @@ -1304,6 +1347,7 @@
|
| return true;
|
| }
|
|
|
| +
|
| void StoreIC::GenerateMiss(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- rax : value
|
| @@ -1322,40 +1366,71 @@
|
| __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1);
|
| }
|
|
|
| -void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
| +
|
| +void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- rax : value
|
| - // -- rcx : Map (target of map transition)
|
| + // -- rcx : name
|
| // -- rdx : receiver
|
| // -- rsp[0] : return address
|
| // -----------------------------------
|
|
|
| - __ pop(rbx);
|
| - __ push(rdx); // receiver
|
| - __ push(rcx); // transition map
|
| - __ push(rax); // value
|
| - __ push(rbx); // return address
|
| + // Get the receiver from the stack and probe the stub cache.
|
| + Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
|
| + NOT_IN_LOOP,
|
| + MONOMORPHIC);
|
| + StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg);
|
|
|
| - // Perform tail call to the entry.
|
| - __ TailCallRuntime(
|
| - ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
|
| + // Cache miss: Jump to runtime.
|
| + GenerateMiss(masm);
|
| }
|
|
|
| -void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
|
| +
|
| +void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- rax : value
|
| // -- rcx : name
|
| // -- rdx : receiver
|
| // -- rsp[0] : return address
|
| // -----------------------------------
|
| + //
|
| + // This accepts as a receiver anything JSObject::SetElementsLength accepts
|
| + // (currently anything except for external and pixel arrays which means
|
| + // anything with elements of FixedArray type.), but currently is restricted
|
| + // to JSArray.
|
| + // Value must be a number, but only smis are accepted as the most common case.
|
|
|
| - // Get the receiver from the stack and probe the stub cache.
|
| - Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
|
| - NOT_IN_LOOP,
|
| - MONOMORPHIC);
|
| - StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg);
|
| + Label miss;
|
|
|
| - // Cache miss: Jump to runtime.
|
| + Register receiver = rdx;
|
| + Register value = rax;
|
| + Register scratch = rbx;
|
| +
|
| + // Check that the receiver isn't a smi.
|
| + __ JumpIfSmi(receiver, &miss);
|
| +
|
| + // Check that the object is a JS array.
|
| + __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch);
|
| + __ j(not_equal, &miss);
|
| +
|
| + // Check that elements are FixedArray.
|
| + __ movq(scratch, FieldOperand(receiver, JSArray::kElementsOffset));
|
| + __ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch);
|
| + __ j(not_equal, &miss);
|
| +
|
| + // Check that value is a smi.
|
| + __ JumpIfNotSmi(value, &miss);
|
| +
|
| + // Prepare tail call to StoreIC_ArrayLength.
|
| + __ pop(scratch);
|
| + __ push(receiver);
|
| + __ push(value);
|
| + __ push(scratch); // return address
|
| +
|
| + __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_ArrayLength)), 2, 1);
|
| +
|
| + __ bind(&miss);
|
| +
|
| GenerateMiss(masm);
|
| }
|
|
|
|
|