Inlined load of string.length and array.length.
http://compute1.aar:9013/golem/r4583-v8-serya-length-inlined-vs-4583-v8.html Review URL: http://codereview.chromium.org/1917006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4601 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
23064a1b28
commit
eaa95c523b
@ -430,8 +430,13 @@ void BreakLocationIterator::SetDebugBreakAtIC() {
|
||||
// is set the patching performed by the runtime system will take place in
|
||||
// the code copy and will therefore have no effect on the running code
|
||||
// keeping it from using the inlined code.
|
||||
if (code->is_keyed_load_stub()) KeyedLoadIC::ClearInlinedVersion(pc());
|
||||
if (code->is_keyed_store_stub()) KeyedStoreIC::ClearInlinedVersion(pc());
|
||||
if (code->is_keyed_load_stub()) {
|
||||
KeyedLoadIC::ClearInlinedVersion(pc());
|
||||
} else if (code->is_keyed_store_stub()) {
|
||||
KeyedStoreIC::ClearInlinedVersion(pc());
|
||||
} else if (code->is_load_stub()) {
|
||||
LoadIC::ClearInlinedVersion(pc());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
14
src/ic.cc
14
src/ic.cc
@ -596,10 +596,16 @@ Object* LoadIC::Load(State state, Handle<Object> object, Handle<String> name) {
|
||||
#ifdef DEBUG
|
||||
if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
|
||||
#endif
|
||||
Map* map = HeapObject::cast(*object)->map();
|
||||
if (object->IsString()) {
|
||||
const int offset = String::kLengthOffset;
|
||||
PatchInlinedLoad(address(), map, offset);
|
||||
}
|
||||
|
||||
Code* target = NULL;
|
||||
target = Builtins::builtin(Builtins::LoadIC_StringLength);
|
||||
set_target(target);
|
||||
StubCache::Set(*name, HeapObject::cast(*object)->map(), target);
|
||||
StubCache::Set(*name, map, target);
|
||||
return Smi::FromInt(String::cast(*object)->length());
|
||||
}
|
||||
|
||||
@ -608,9 +614,13 @@ Object* LoadIC::Load(State state, Handle<Object> object, Handle<String> name) {
|
||||
#ifdef DEBUG
|
||||
if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
|
||||
#endif
|
||||
Map* map = HeapObject::cast(*object)->map();
|
||||
const int offset = JSArray::kLengthOffset;
|
||||
PatchInlinedLoad(address(), map, offset);
|
||||
|
||||
Code* target = Builtins::builtin(Builtins::LoadIC_ArrayLength);
|
||||
set_target(target);
|
||||
StubCache::Set(*name, HeapObject::cast(*object)->map(), target);
|
||||
StubCache::Set(*name, map, target);
|
||||
return JSArray::cast(*object)->length();
|
||||
}
|
||||
|
||||
|
6
src/ic.h
6
src/ic.h
@ -239,6 +239,9 @@ class LoadIC: public IC {
|
||||
static void GenerateStringLength(MacroAssembler* masm);
|
||||
static void GenerateFunctionPrototype(MacroAssembler* masm);
|
||||
|
||||
// Clear the use of the inlined version.
|
||||
static void ClearInlinedVersion(Address address);
|
||||
|
||||
// The offset from the inlined patch site to the start of the
|
||||
// inlined load instruction. It is architecture-dependent, and not
|
||||
// used on ARM.
|
||||
@ -265,9 +268,6 @@ class LoadIC: public IC {
|
||||
|
||||
static void Clear(Address address, Code* target);
|
||||
|
||||
// Clear the use of the inlined version.
|
||||
static void ClearInlinedVersion(Address address);
|
||||
|
||||
static bool PatchInlinedLoad(Address address, Object* map, int index);
|
||||
|
||||
friend class IC;
|
||||
|
@ -2511,6 +2511,50 @@ TEST(DebugStepKeyedStoreLoop) {
|
||||
}
|
||||
|
||||
|
||||
// Test of the stepping mechanism for named load in a loop.
|
||||
TEST(DebugStepNamedLoadLoop) {
|
||||
v8::HandleScope scope;
|
||||
DebugLocalContext env;
|
||||
|
||||
// Create a function for testing stepping of named load.
|
||||
v8::Local<v8::Function> foo = CompileFunction(
|
||||
&env,
|
||||
"function foo() {\n"
|
||||
" var a = [];\n"
|
||||
" var s = \"\";\n"
|
||||
" for (var i = 0; i < 10; i++) {\n"
|
||||
" var v = new V(i, i + 1);\n"
|
||||
" v.y;\n"
|
||||
" a.length;\n" // Special case: array length.
|
||||
" s.length;\n" // Special case: string length.
|
||||
" }\n"
|
||||
"}\n"
|
||||
"function V(x, y) {\n"
|
||||
" this.x = x;\n"
|
||||
" this.y = y;\n"
|
||||
"}\n",
|
||||
"foo");
|
||||
|
||||
// Call function without any break points to ensure inlining is in place.
|
||||
foo->Call(env->Global(), 0, NULL);
|
||||
|
||||
// Register a debug event listener which steps and counts.
|
||||
v8::Debug::SetDebugEventListener(DebugEventStep);
|
||||
|
||||
// Setup break point and step through the function.
|
||||
SetBreakPoint(foo, 4);
|
||||
step_action = StepNext;
|
||||
break_point_hit_count = 0;
|
||||
foo->Call(env->Global(), 0, NULL);
|
||||
|
||||
// With stepping all break locations are hit.
|
||||
CHECK_EQ(41, break_point_hit_count);
|
||||
|
||||
v8::Debug::SetDebugEventListener(NULL);
|
||||
CheckDebuggerUnloaded();
|
||||
}
|
||||
|
||||
|
||||
// Test the stepping mechanism with different ICs.
|
||||
TEST(DebugStepLinearMixedICs) {
|
||||
v8::HandleScope scope;
|
||||
|
Loading…
Reference in New Issue
Block a user