Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(541)

Unified Diff: src/ia32/stub-cache-ia32.cc

Issue 6894003: Better support for 'polymorphic' JS and external arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: new strategy Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic.h » ('j') | src/ic.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/stub-cache-ia32.cc
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index c6251157f28c373895feecbaba9e609023203ef9..9ff682625ed0cfdbeeea019cc10879dd90c25815 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -758,6 +758,14 @@ void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
}
+void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
+ Code* code = masm->isolate()->builtins()->builtin(
+ Builtins::kKeyedLoadIC_MissForceGeneric);
Mads Ager (chromium) 2011/04/28 13:02:01 Four space indent?
+ Handle<Code> ic(code);
+ __ jmp(ic, RelocInfo::CODE_TARGET);
+}
+
+
// Both name_reg and receiver_reg are preserved on jumps to miss_label,
// but may be destroyed if store is successful.
void StubCompiler::GenerateStoreField(MacroAssembler* masm,
@@ -2694,42 +2702,34 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
}
-MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(
- JSObject* receiver) {
+MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(Handle<Map> receiver_map) {
// ----------- S t a t e -------------
// -- eax : value
// -- ecx : key
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
- Label miss;
+ Label miss, miss_force_generic;
- // Check that the receiver isn't a smi.
- __ test(edx, Immediate(kSmiTagMask));
- __ j(zero, &miss, not_taken);
-
- // Check that the map matches.
- __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- Immediate(Handle<Map>(receiver->map())));
- __ j(not_equal, &miss, not_taken);
+ __ CheckMap(edx, receiver_map, &miss, false);
// Check that the key is a smi.
__ test(ecx, Immediate(kSmiTagMask));
- __ j(not_zero, &miss, not_taken);
+ __ j(not_zero, &miss_force_generic, not_taken);
// Get the elements array and make sure it is a fast element array, not 'cow'.
__ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
__ cmp(FieldOperand(edi, HeapObject::kMapOffset),
Immediate(factory()->fixed_array_map()));
- __ j(not_equal, &miss, not_taken);
+ __ j(not_equal, &miss_force_generic, not_taken);
// Check that the key is within bounds.
- if (receiver->IsJSArray()) {
- __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
- __ j(above_equal, &miss, not_taken);
+ if (receiver_map->instance_type() == JS_ARRAY_TYPE) {
+ __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
+ __ j(above_equal, &miss_force_generic, not_taken);
} else {
- __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // Compare smis.
- __ j(above_equal, &miss, not_taken);
+ __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis.
+ __ j(above_equal, &miss_force_generic, not_taken);
}
// Do the store and update the write barrier. Make sure to preserve
@@ -2746,11 +2746,43 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(
Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
+ // Handle store cache miss, replacing the ic with the generic stub.
+ __ bind(&miss_force_generic);
+ Handle<Code> ic_force_generic =
+ isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
+ __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
+
// Return the generated code.
return GetCode(NORMAL, NULL);
}
+MaybeObject* KeyedStoreStubCompiler::CompileStoreMegamorphic(
+ ZoneMapList* receiver_maps,
+ ZoneCodeList* handler_ics) {
+ // ----------- S t a t e -------------
+ // -- eax : receiver
+ // -- ecx : name
+ // -- esp[0] : return address
+ // -----------------------------------
+ Label miss;
+ __ JumpIfSmi(eax, &miss);
+
+ int receiver_count = receiver_maps->length();
+ for (int current = 0; current < receiver_count; ++current) {
+ // Check map and tail call if there's a match
+ __ cmp(FieldOperand(edx, HeapObject::kMapOffset), receiver_maps->at(current));
+ __ j(equal, handler_ics->at(current));
+ }
+ __ bind(&miss);
+ Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
+ __ jmp(ic, RelocInfo::CODE_TARGET);
+
+ // Return the generated code.
+ return GetCode(NORMAL, NULL, MEGAMORPHIC);
+}
+
+
MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
JSObject* object,
JSObject* last) {
@@ -3160,26 +3192,20 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
}
-MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) {
+MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(
+ Handle<Map> receiver_map) {
// ----------- S t a t e -------------
// -- eax : key
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
- Label miss;
+ Label miss, miss_force_generic;
- // Check that the receiver isn't a smi.
- __ test(edx, Immediate(kSmiTagMask));
- __ j(zero, &miss, not_taken);
-
- // Check that the map matches.
- __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- Immediate(Handle<Map>(receiver->map())));
- __ j(not_equal, &miss, not_taken);
+ __ CheckMap(edx, receiver_map, &miss, false);
// Check that the key is a smi.
__ test(eax, Immediate(kSmiTagMask));
- __ j(not_zero, &miss, not_taken);
+ __ j(not_zero, &miss_force_generic, not_taken);
// Get the elements array.
__ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
@@ -3187,24 +3213,53 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) {
// Check that the key is within bounds.
__ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
- __ j(above_equal, &miss, not_taken);
+ __ j(above_equal, &miss_force_generic, not_taken);
// Load the result and make sure it's not the hole.
__ mov(ebx, Operand(ecx, eax, times_2,
FixedArray::kHeaderSize - kHeapObjectTag));
__ cmp(ebx, factory()->the_hole_value());
- __ j(equal, &miss, not_taken);
+ __ j(equal, &miss_force_generic, not_taken);
__ mov(eax, ebx);
__ ret(0);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+ __ bind(&miss_force_generic);
+ GenerateKeyedLoadMissForceGeneric(masm());
+
// Return the generated code.
return GetCode(NORMAL, NULL);
}
+MaybeObject* KeyedLoadStubCompiler::CompileLoadMegamorphic(
+ ZoneMapList* receiver_maps,
+ ZoneCodeList* handler_ics) {
+ // ----------- S t a t e -------------
+ // -- eax : key
+ // -- edx : receiver
+ // -- esp[0] : return address
+ // -----------------------------------
+ Label miss;
+
+ __ JumpIfSmi(eax, &miss);
+
+ int receiver_count = receiver_maps->length();
+ for (int current = 0; current < receiver_count; ++current) {
+ // Check map and tail call if there's a match
+ __ cmp(FieldOperand(edx, HeapObject::kMapOffset), receiver_maps->at(current));
+ __ j(equal, handler_ics->at(current));
+ }
+ __bind(&miss);
+ GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+
+ // Return the generated code.
+ return GetCode(NORMAL, NULL, MEGAMORPHIC);
+}
+
+
// Specialized stub for constructing objects from functions which only have only
// simple assignments of the form this.x = ...; in their body.
MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
@@ -3351,18 +3406,18 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
- Label slow, failed_allocation;
+ Label slow, failed_allocation, miss;
// Check that the object isn't a smi.
__ test(edx, Immediate(kSmiTagMask));
- __ j(zero, &slow, not_taken);
+ __ j(zero, &miss, not_taken);
// Check that the key is a smi.
__ test(eax, Immediate(kSmiTagMask));
- __ j(not_zero, &slow, not_taken);
+ __ j(not_zero, &miss, not_taken);
// Check that the map matches.
- __ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false);
+ __ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false);
__ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
// eax: key, known to be a smi.
@@ -3373,7 +3428,7 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
__ SmiUntag(ecx); // Untag the index.
__ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
// Unsigned comparison catches both negative and too-large values.
- __ j(above_equal, &slow);
+ __ j(above_equal, &miss);
__ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
// ebx: base pointer of external storage
switch (array_type) {
@@ -3482,19 +3537,25 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
__ bind(&slow);
Counters* counters = isolate()->counters();
__ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
+
// ----------- S t a t e -------------
// -- eax : key
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
- __ pop(ebx);
- __ push(edx); // receiver
- __ push(eax); // name
- __ push(ebx); // return address
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Slow();
+ __ jmp(ic, RelocInfo::CODE_TARGET);
+
+ __ bind(&miss);
+ // ----------- S t a t e -------------
+ // -- eax : key
+ // -- edx : receiver
+ // -- esp[0] : return address
+ // -----------------------------------
- // Perform tail call to the entry.
- __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
+ Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss();
+ __ jmp(miss_ic, RelocInfo::CODE_TARGET);
// Return the generated code.
return GetCode(flags);
@@ -3509,18 +3570,18 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
- Label slow, check_heap_number;
+ Label slow, check_heap_number, miss;
// Check that the object isn't a smi.
__ test(edx, Immediate(kSmiTagMask));
- __ j(zero, &slow);
+ __ j(zero, &miss);
// Check that the map matches.
- __ CheckMap(edx, Handle<Map>(receiver->map()), &slow, false);
+ __ CheckMap(edx, Handle<Map>(receiver->map()), &miss, false);
// Check that the key is a smi.
__ test(ecx, Immediate(kSmiTagMask));
- __ j(not_zero, &slow);
+ __ j(not_zero, &miss);
// Check that the index is in range.
__ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
@@ -3694,6 +3755,9 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
// Slow case: call runtime.
__ bind(&slow);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->keyed_store_external_array_slow(), 1);
+
// ----------- S t a t e -------------
// -- eax : value
// -- ecx : key
@@ -3701,17 +3765,23 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
// -- esp[0] : return address
// -----------------------------------
- __ pop(ebx);
- __ push(edx);
- __ push(ecx);
- __ push(eax);
- __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes
- __ push(Immediate(Smi::FromInt(
- Code::ExtractExtraICStateFromFlags(flags) & kStrictMode)));
- __ push(ebx); // return address
-
- // Do tail-call to runtime routine.
- __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
+ bool strict = (Code::ExtractExtraICStateFromFlags(flags) & kStrictMode) != 0;
+ Handle<Code> ic = strict
+ ? isolate()->builtins()->KeyedStoreIC_Slow_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Slow_NonStrict();
+ __ jmp(ic, RelocInfo::CODE_TARGET);
+
+ // Miss case: call runtime.
+ __ bind(&miss);
+ // ----------- S t a t e -------------
+ // -- eax : value
+ // -- ecx : key
+ // -- edx : receiver
+ // -- esp[0] : return address
+ // -----------------------------------
+
+ Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss();
+ __ jmp(miss_ic, RelocInfo::CODE_TARGET);
return GetCode(flags);
}
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic.h » ('j') | src/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698