}
+void ArrayLengthStub::Generate(MacroAssembler* masm) {
+ Label miss;
+ Register receiver;
+ if (kind() == Code::KEYED_LOAD_IC) {
+ // ----------- S t a t e -------------
+ // -- lr : return address
+ // -- r0 : key
+ // -- r1 : receiver
+ // -----------------------------------
+ __ cmp(r0, Operand(masm->isolate()->factory()->length_symbol()));
+ __ b(ne, &miss);
+ receiver = r1;
+ } else {
+ ASSERT(kind() == Code::LOAD_IC);
+ // ----------- S t a t e -------------
+ // -- r2 : name
+ // -- lr : return address
+ // -- r0 : receiver
+ // -- sp[0] : receiver
+ // -----------------------------------
+ receiver = r0;
+ }
+
+ StubCompiler::GenerateLoadArrayLength(masm, receiver, r3, &miss);
+ __ bind(&miss);
+ StubCompiler::GenerateLoadMiss(masm, kind());
+}
+
+
void StringLengthStub::Generate(MacroAssembler* masm) {
Label miss;
Register receiver;
}
-void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- r2 : name
- // -- lr : return address
- // -- r0 : receiver
- // -- sp[0] : receiver
- // -----------------------------------
- Label miss;
-
- StubCompiler::GenerateLoadArrayLength(masm, r0, r3, &miss);
- __ bind(&miss);
- StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
-}
-
-
void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : name
}
-Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
- Handle<String> name) {
- // ----------- S t a t e -------------
- // -- lr : return address
- // -- r0 : key
- // -- r1 : receiver
- // -----------------------------------
- Label miss;
-
- // Check the key is the cached one.
- __ cmp(r0, Operand(name));
- __ b(ne, &miss);
-
- GenerateLoadArrayLength(masm(), r1, r2, &miss);
- __ bind(&miss);
- GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
- return GetCode(Code::CALLBACKS, name);
-}
-
-
Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
Handle<String> name) {
// ----------- S t a t e -------------
is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
receiver_types_.Clear();
if (key()->IsPropertyName()) {
+ ArrayLengthStub array_stub(Code::LOAD_IC);
StringLengthStub string_stub(Code::LOAD_IC, false);
- if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) {
+ if (oracle->LoadIsStub(this, &array_stub)) {
is_array_length_ = true;
} else if (oracle->LoadIsStub(this, &string_stub)) {
is_string_length_ = true;
}
-static void Generate_LoadIC_ArrayLength(MacroAssembler* masm) {
- LoadIC::GenerateArrayLength(masm);
-}
-
-
static void Generate_LoadIC_FunctionPrototype(MacroAssembler* masm) {
LoadIC::GenerateFunctionPrototype(masm);
}
Code::kNoExtraICState) \
V(LoadIC_Normal, LOAD_IC, MONOMORPHIC, \
Code::kNoExtraICState) \
- V(LoadIC_ArrayLength, LOAD_IC, MONOMORPHIC, \
- Code::kNoExtraICState) \
V(LoadIC_FunctionPrototype, LOAD_IC, MONOMORPHIC, \
Code::kNoExtraICState) \
V(LoadIC_Megamorphic, LOAD_IC, MEGAMORPHIC, \
V(Compare) \
V(CompareIC) \
V(MathPow) \
+ V(ArrayLength) \
V(StringLength) \
V(RecordWrite) \
V(StoreBufferOverflow) \
}
Code::Kind kind() { return kind_; }
+ virtual int MinorKey() {
+ return KindBits::encode(kind_);
+ }
+
private:
Code::Kind kind_;
};
+class ArrayLengthStub: public ICStub {
+ public:
+ explicit ArrayLengthStub(Code::Kind kind) : ICStub(kind) { }
+ virtual void Generate(MacroAssembler* masm);
+
+ private:
+ virtual CodeStub::Major MajorKey() { return ArrayLength; }
+};
+
+
class StringLengthStub: public ICStub {
public:
StringLengthStub(Code::Kind kind, bool support_wrapper)
}
+void ArrayLengthStub::Generate(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- ecx : name
+ // -- edx : receiver
+ // -- esp[0] : return address
+ // -----------------------------------
+ Label miss;
+
+ if (kind() == Code::KEYED_LOAD_IC) {
+ __ cmp(ecx, Immediate(masm->isolate()->factory()->length_symbol()));
+ __ j(not_equal, &miss);
+ }
+
+ StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss);
+ __ bind(&miss);
+ StubCompiler::GenerateLoadMiss(masm, kind());
+}
+
+
void StringLengthStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- ecx : name
}
-void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- ecx : name
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
- Label miss;
-
- StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss);
- __ bind(&miss);
- StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
-}
-
-
void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- ecx : name
}
-Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
- Handle<String> name) {
- // ----------- S t a t e -------------
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
- Label miss;
-
- Counters* counters = isolate()->counters();
- __ IncrementCounter(counters->keyed_load_array_length(), 1);
-
- // Check that the name has not changed.
- __ cmp(ecx, Immediate(name));
- __ j(not_equal, &miss);
-
- GenerateLoadArrayLength(masm(), edx, eax, &miss);
- __ bind(&miss);
- __ DecrementCounter(counters->keyed_load_array_length(), 1);
- GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
- // Return the generated code.
- return GetCode(Code::CALLBACKS, name);
-}
-
-
Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
Handle<String> name) {
// ----------- S t a t e -------------
*result = Smi::FromInt(String::cast(*string)->length());
return true;
}
+
+ // Use specialized code for getting the length of arrays.
+ if (object->IsJSArray() && name->Equals(isolate()->heap()->length_symbol())) {
+ Handle<Code> stub;
+ if (state == UNINITIALIZED) {
+ stub = pre_monomorphic_stub();
+ } else if (state == PREMONOMORPHIC) {
+ ArrayLengthStub array_length_stub(kind());
+ stub = array_length_stub.GetCode();
+ } else if (state != MEGAMORPHIC) {
+ ASSERT(state != GENERIC);
+ stub = megamorphic_stub();
+ }
+ if (!stub.is_null()) {
+ set_target(*stub);
+#ifdef DEBUG
+ if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
+#endif
+ }
+ *result = JSArray::cast(*object)->length();
+ return true;
+ }
+
return false;
}
return result;
}
- // Use specialized code for getting the length of arrays.
- if (object->IsJSArray() &&
- name->Equals(isolate()->heap()->length_symbol())) {
- Handle<Code> stub;
- if (state == UNINITIALIZED) {
- stub = pre_monomorphic_stub();
- } else if (state == PREMONOMORPHIC) {
- stub = isolate()->builtins()->LoadIC_ArrayLength();
- } else if (state != MEGAMORPHIC) {
- ASSERT(state != GENERIC);
- stub = megamorphic_stub();
- }
- if (!stub.is_null()) {
- set_target(*stub);
-#ifdef DEBUG
- if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
-#endif
- }
- return JSArray::cast(*object)->length();
- }
-
// Use specialized code for getting prototype of functions.
if (object->IsJSFunction() &&
name->Equals(isolate()->heap()->prototype_symbol()) &&
}
// TODO(1073): don't ignore the current stub state.
- // Use specialized code for getting the length of arrays.
- if (object->IsJSArray() &&
- name->Equals(isolate()->heap()->length_symbol())) {
- Handle<JSArray> array = Handle<JSArray>::cast(object);
- Handle<Code> code =
- isolate()->stub_cache()->ComputeKeyedLoadArrayLength(name, array);
- ASSERT(!code.is_null());
- set_target(*code);
- TRACE_IC("KeyedLoadIC", name, state, target());
- return array->length();
- }
-
// Use specialized code for getting prototype of functions.
if (object->IsJSFunction() &&
name->Equals(isolate()->heap()->prototype_symbol()) &&
}
-Handle<Code> StubCache::ComputeKeyedLoadArrayLength(Handle<String> name,
- Handle<JSArray> receiver) {
- Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
- Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
- isolate_);
- if (probe->IsCode()) return Handle<Code>::cast(probe);
-
- KeyedLoadStubCompiler compiler(isolate_);
- Handle<Code> code = compiler.CompileLoadArrayLength(name);
- PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
- GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
- JSObject::UpdateMapCodeCache(receiver, name, code);
- return code;
-}
-
-
Handle<Code> StubCache::ComputeKeyedLoadFunctionPrototype(
Handle<String> name,
Handle<JSFunction> receiver) {
Handle<JSObject> receiver,
Handle<JSObject> holder);
- Handle<Code> ComputeKeyedLoadArrayLength(Handle<String> name,
- Handle<JSArray> receiver);
-
Handle<Code> ComputeKeyedLoadFunctionPrototype(Handle<String> name,
Handle<JSFunction> receiver);
Handle<JSObject> holder,
Handle<String> name);
- Handle<Code> CompileLoadArrayLength(Handle<String> name);
-
Handle<Code> CompileLoadFunctionPrototype(Handle<String> name);
Handle<Code> CompileLoadElement(Handle<Map> receiver_map);
}
+void ArrayLengthStub::Generate(MacroAssembler* masm) {
+ Label miss;
+ Register receiver;
+ if (kind() == Code::KEYED_LOAD_IC) {
+ // ----------- S t a t e -------------
+ // -- rax : key
+ // -- rdx : receiver
+ // -- rsp[0] : return address
+ // -----------------------------------
+ __ Cmp(rax, masm->isolate()->factory()->length_symbol());
+ receiver = rdx;
+ } else {
+ ASSERT(kind() == Code::LOAD_IC);
+ // ----------- S t a t e -------------
+ // -- rax : receiver
+ // -- rcx : name
+ // -- rsp[0] : return address
+ // -----------------------------------
+ receiver = rax;
+ }
+
+ StubCompiler::GenerateLoadArrayLength(masm, receiver, r8, &miss);
+ __ bind(&miss);
+ StubCompiler::GenerateLoadMiss(masm, kind());
+}
+
+
void StringLengthStub::Generate(MacroAssembler* masm) {
Label miss;
Register receiver;
}
-void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : receiver
- // -- rcx : name
- // -- rsp[0] : return address
- // -----------------------------------
- Label miss;
-
- StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss);
- __ bind(&miss);
- StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
-}
-
-
void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : receiver
}
-Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
- Handle<String> name) {
- // ----------- S t a t e -------------
- // -- rax : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
- Label miss;
-
- Counters* counters = isolate()->counters();
- __ IncrementCounter(counters->keyed_load_array_length(), 1);
-
- // Check that the name has not changed.
- __ Cmp(rax, name);
- __ j(not_equal, &miss);
-
- GenerateLoadArrayLength(masm(), rdx, rcx, &miss);
- __ bind(&miss);
- __ DecrementCounter(counters->keyed_load_array_length(), 1);
- GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
- // Return the generated code.
- return GetCode(Code::CALLBACKS, name);
-}
-
-
Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
Handle<String> name) {
// ----------- S t a t e -------------