From: vitalyr@chromium.org Date: Wed, 14 Apr 2010 20:16:19 +0000 (+0000) Subject: One less dependent load in InvokeBuiltin. X-Git-Tag: upstream/4.7.83~22008 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1d8ec1e47b24edeee2cefad795eb1e56250e0fb5;p=platform%2Fupstream%2Fv8.git One less dependent load in InvokeBuiltin. Review URL: http://codereview.chromium.org/1638006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4423 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index 1131760..c0c8246 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -1309,15 +1309,29 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { + ASSERT(!target.is(r1)); + + // Load the builtins object into target register. + ldr(target, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); + ldr(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset)); + // Load the JavaScript builtin function from the builtins object. - ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); - ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset)); - int builtins_offset = - JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize); - ldr(r1, FieldMemOperand(r1, builtins_offset)); - // Load the code entry point from the function into the target register. - ldr(target, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); - ldr(target, FieldMemOperand(target, SharedFunctionInfo::kCodeOffset)); + ldr(r1, FieldMemOperand(target, + JSBuiltinsObject::OffsetOfFunctionWithId(id))); + + // Load the code entry point from the builtins object. + ldr(target, FieldMemOperand(target, + JSBuiltinsObject::OffsetOfCodeWithId(id))); + if (FLAG_debug_code) { + // Make sure the code objects in the builtins object and in the + // builtin function are the same. + push(r1); + ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); + ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kCodeOffset)); + cmp(r1, target); + Assert(eq, "Builtin code object changed"); + pop(r1); + } add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); } diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 3dd7c4a..ac9663d 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -1492,6 +1492,7 @@ bool Genesis::InstallJSBuiltins(Handle builtins) { Handle shared = Handle(function->shared()); if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; + builtins->set_javascript_builtin_code(id, shared->code()); } return true; } diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc index 3529336..66f5638 100644 --- a/src/ia32/macro-assembler-ia32.cc +++ b/src/ia32/macro-assembler-ia32.cc @@ -1396,16 +1396,28 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { + ASSERT(!target.is(edi)); + + // Load the builtins object into target register. + mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); + mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); + // Load the JavaScript builtin function from the builtins object. - mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); - mov(edi, FieldOperand(edi, GlobalObject::kBuiltinsOffset)); - int builtins_offset = - JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize); - mov(edi, FieldOperand(edi, builtins_offset)); - // Load the code entry point from the function into the target register. - mov(target, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); - mov(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset)); - add(Operand(target), Immediate(Code::kHeaderSize - kHeapObjectTag)); + mov(edi, FieldOperand(target, JSBuiltinsObject::OffsetOfFunctionWithId(id))); + + // Load the code entry point from the builtins object. + mov(target, FieldOperand(target, JSBuiltinsObject::OffsetOfCodeWithId(id))); + if (FLAG_debug_code) { + // Make sure the code objects in the builtins object and in the + // builtin function are the same. + push(target); + mov(target, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); + mov(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset)); + cmp(target, Operand(esp, 0)); + Assert(equal, "Builtin code object changed"); + pop(target); + } + lea(target, FieldOperand(target, Code::kHeaderSize)); } diff --git a/src/objects-inl.h b/src/objects-inl.h index d363d4d..a21a735 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -2587,15 +2587,29 @@ int JSFunction::NumberOfLiterals() { Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) { ASSERT(0 <= id && id < kJSBuiltinsCount); - return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize)); + return READ_FIELD(this, OffsetOfFunctionWithId(id)); } void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id, Object* value) { ASSERT(0 <= id && id < kJSBuiltinsCount); - WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value); - WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize)); + WRITE_FIELD(this, OffsetOfFunctionWithId(id), value); + WRITE_BARRIER(this, OffsetOfFunctionWithId(id)); +} + + +Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) { + ASSERT(0 <= id && id < kJSBuiltinsCount); + return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id))); +} + + +void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id, + Code* value) { + ASSERT(0 <= id && id < kJSBuiltinsCount); + WRITE_FIELD(this, OffsetOfCodeWithId(id), value); + ASSERT(!Heap::InNewSpace(value)); } diff --git a/src/objects.h b/src/objects.h index 0167834..aa60e63 100644 --- a/src/objects.h +++ b/src/objects.h @@ -3543,6 +3543,10 @@ class JSBuiltinsObject: public GlobalObject { inline Object* javascript_builtin(Builtins::JavaScript id); inline void set_javascript_builtin(Builtins::JavaScript id, Object* value); + // Accessors for code of the runtime routines written in JavaScript. + inline Code* javascript_builtin_code(Builtins::JavaScript id); + inline void set_javascript_builtin_code(Builtins::JavaScript id, Code* value); + // Casting. static inline JSBuiltinsObject* cast(Object* obj); @@ -3553,11 +3557,23 @@ class JSBuiltinsObject: public GlobalObject { #endif // Layout description. The size of the builtins object includes - // room for one pointer per runtime routine written in javascript. + // room for two pointers per runtime routine written in javascript + // (function and code object). static const int kJSBuiltinsCount = Builtins::id_count; static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize; + static const int kJSBuiltinsCodeOffset = + GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize); static const int kSize = - kJSBuiltinsOffset + (kJSBuiltinsCount * kPointerSize); + kJSBuiltinsCodeOffset + (kJSBuiltinsCount * kPointerSize); + + static int OffsetOfFunctionWithId(Builtins::JavaScript id) { + return kJSBuiltinsOffset + id * kPointerSize; + } + + static int OffsetOfCodeWithId(Builtins::JavaScript id) { + return kJSBuiltinsCodeOffset + id * kPointerSize; + } + private: DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject); }; diff --git a/src/serialize.h b/src/serialize.h index ab2ae9f..279bc58 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -503,7 +503,8 @@ class PartialSerializer : public Serializer { // unique ID, and deserializing several partial snapshots containing script // would cause dupes. ASSERT(!o->IsScript()); - return o->IsString() || o->IsSharedFunctionInfo() || o->IsHeapNumber(); + return o->IsString() || o->IsSharedFunctionInfo() || + o->IsHeapNumber() || o->IsCode(); } private: diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index 2c47cf8..61cfaa2 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -445,16 +445,28 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { + ASSERT(!target.is(rdi)); + + // Load the builtins object into target register. + movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); + movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); + // Load the JavaScript builtin function from the builtins object. - movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); - movq(rdi, FieldOperand(rdi, GlobalObject::kBuiltinsOffset)); - int builtins_offset = - JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize); - movq(rdi, FieldOperand(rdi, builtins_offset)); - // Load the code entry point from the function into the target register. - movq(target, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); - movq(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset)); - addq(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); + movq(rdi, FieldOperand(target, JSBuiltinsObject::OffsetOfFunctionWithId(id))); + + // Load the code entry point from the builtins object. + movq(target, FieldOperand(target, JSBuiltinsObject::OffsetOfCodeWithId(id))); + if (FLAG_debug_code) { + // Make sure the code objects in the builtins object and in the + // builtin function are the same. + push(target); + movq(target, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); + movq(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset)); + cmpq(target, Operand(rsp, 0)); + Assert(equal, "Builtin code object changed"); + pop(target); + } + lea(target, FieldOperand(target, Code::kHeaderSize)); }