Revision: 3832
Author: [email protected]
Date: Thu Feb 11 00:05:33 2010
Log: Always load the JavaScript builtins code entry from the JavaScript
function instead of baking in the address of the first one that we see
in code.

This removes the need for fixups processing and makes the stubs safe
when there is no natives cache and therefore multiple versions of the
builtin functions.

Review URL: http://codereview.chromium.org/594009
http://code.google.com/p/v8/source/detail?r=3832

Modified:
 /branches/bleeding_edge/src/arm/macro-assembler-arm.cc
 /branches/bleeding_edge/src/arm/macro-assembler-arm.h
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/bootstrapper.h
 /branches/bleeding_edge/src/builtins.cc
 /branches/bleeding_edge/src/code-stubs.cc
 /branches/bleeding_edge/src/codegen.cc
 /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
 /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h
 /branches/bleeding_edge/src/x64/macro-assembler-x64.cc
 /branches/bleeding_edge/src/x64/macro-assembler-x64.h

=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Mon Feb 8 05:44:49 2010 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Thu Feb 11 00:05:33 2010
@@ -37,7 +37,6 @@

 MacroAssembler::MacroAssembler(void* buffer, int size)
     : Assembler(buffer, size),
-      unresolved_(0),
       generating_stub_(false),
       allow_stub_calls_(true),
       code_object_(Heap::undefined_value()) {
@@ -1231,60 +1230,30 @@
   CEntryStub stub(1);
   Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
 }
-
-
-Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
-                                            bool* resolved) {
-  // Contract with compiled functions is that the function is passed in r1.
-  int builtins_offset =
-      JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
-  ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
-  ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
-  ldr(r1, FieldMemOperand(r1, builtins_offset));
-
-  return Builtins::GetCode(id, resolved);
-}


 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
                                    InvokeJSFlags flags) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
-
+  GetBuiltinEntry(r2, id);
   if (flags == CALL_JS) {
-    Call(code, RelocInfo::CODE_TARGET);
+    Call(r2);
   } else {
     ASSERT(flags == JUMP_JS);
-    Jump(code, RelocInfo::CODE_TARGET);
-  }
-
-  if (!resolved) {
-    const char* name = Builtins::GetName(id);
-    int argc = Builtins::GetArgumentsCount(id);
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(false);
-    Unresolved entry = { pc_offset() - kInstrSize, flags, name };
-    unresolved_.Add(entry);
+    Jump(r2);
   }
 }


void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
-
-  mov(target, Operand(code));
-  if (!resolved) {
-    const char* name = Builtins::GetName(id);
-    int argc = Builtins::GetArgumentsCount(id);
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(true);
-    Unresolved entry = { pc_offset() - kInstrSize, flags, name };
-    unresolved_.Add(entry);
-  }
-
+  // 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));
   add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
 }

=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Mon Feb 8 05:44:49 2010 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Thu Feb 11 00:05:33 2010
@@ -353,13 +353,6 @@
   // setup the function in r1.
   void GetBuiltinEntry(Register target, Builtins::JavaScript id);

-  struct Unresolved {
-    int pc;
-    uint32_t flags;  // see Bootstrapper::FixupFlags decoders/encoders.
-    const char* name;
-  };
-  List<Unresolved>* unresolved() { return &unresolved_; }
-
   Handle<Object> CodeObject() { return code_object_; }


@@ -432,23 +425,10 @@
                       Label* done,
                       InvokeFlag flag);

-  // Prepares for a call or jump to a builtin by doing two things:
- // 1. Emits code that fetches the builtin's function object from the context
-  //    at runtime, and puts it in the register rdi.
-  // 2. Fetches the builtin's code object, and returns it in a handle, at
- // compile time, so that later code can emit instructions to jump or call - // the builtin directly. If the code object has not yet been created, it
-  //    returns the builtin code object for IllegalFunction, and sets the
- // output parameter "resolved" to false. Code that uses the return value - // should then add the address and the builtin name to the list of fixups
-  //    called unresolved_, which is fixed up by the bootstrapper.
-  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
-
   // Activation support.
   void EnterFrame(StackFrame::Type type);
   void LeaveFrame(StackFrame::Type type);

-  List<Unresolved> unresolved_;
   bool generating_stub_;
   bool allow_stub_calls_;
   // This handle will be patched with the code object on installation.
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Fri Jan 29 01:52:51 2010
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu Feb 11 00:05:33 2010
@@ -190,116 +190,6 @@
   natives_cache.Initialize(false);  // Yes, symmetrical
   extensions_cache.Initialize(false);
 }
-
-
-// Pending fixups are code positions that refer to builtin code
-// objects that were not available at the time the code was generated.
-// The pending list is processed whenever an environment has been
-// created.
-class PendingFixups : public AllStatic {
- public:
-  static void Add(Code* code, MacroAssembler* masm);
-  static bool Process(Handle<JSBuiltinsObject> builtins);
-
-  static void Iterate(ObjectVisitor* v);
-
- private:
-  static List<Object*> code_;
-  static List<const char*> name_;
-  static List<int> pc_;
-  static List<uint32_t> flags_;
-
-  static void Clear();
-};
-
-
-List<Object*> PendingFixups::code_(0);
-List<const char*> PendingFixups::name_(0);
-List<int> PendingFixups::pc_(0);
-List<uint32_t> PendingFixups::flags_(0);
-
-
-void PendingFixups::Add(Code* code, MacroAssembler* masm) {
-  // Note this code is not only called during bootstrapping.
-  List<MacroAssembler::Unresolved>* unresolved = masm->unresolved();
-  int n = unresolved->length();
-  for (int i = 0; i < n; i++) {
-    const char* name = unresolved->at(i).name;
-    code_.Add(code);
-    name_.Add(name);
-    pc_.Add(unresolved->at(i).pc);
-    flags_.Add(unresolved->at(i).flags);
-    LOG(StringEvent("unresolved", name));
-  }
-}
-
-
-bool PendingFixups::Process(Handle<JSBuiltinsObject> builtins) {
-  HandleScope scope;
-  // NOTE: Extra fixups may be added to the list during the iteration
-  // due to lazy compilation of functions during the processing. Do not
-  // cache the result of getting the length of the code list.
-  for (int i = 0; i < code_.length(); i++) {
-    const char* name = name_[i];
-    uint32_t flags = flags_[i];
-    Handle<String> symbol = Factory::LookupAsciiSymbol(name);
-    Object* o = builtins->GetProperty(*symbol);
-#ifdef DEBUG
-    if (!o->IsJSFunction()) {
- V8_Fatal(__FILE__, __LINE__, "Cannot resolve call to builtin %s", name);
-    }
-#endif
-    Handle<SharedFunctionInfo> shared(JSFunction::cast(o)->shared());
-    // Make sure the number of parameters match the formal parameter count.
-    int argc = Bootstrapper::FixupFlagsArgumentsCount::decode(flags);
-    USE(argc);
-    ASSERT(shared->formal_parameter_count() == argc);
-    // Do lazy compilation if necessary and check for stack overflows.
-    if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) {
-      Clear();
-      return false;
-    }
-    Code* code = Code::cast(code_[i]);
-    Address pc = code->instruction_start() + pc_[i];
-    RelocInfo target(pc, RelocInfo::CODE_TARGET, 0);
- bool use_code_object = Bootstrapper::FixupFlagsUseCodeObject::decode(flags);
-    if (use_code_object) {
-      target.set_target_object(shared->code());
-    } else {
-      target.set_target_address(shared->code()->instruction_start());
-    }
-    LOG(StringEvent("resolved", name));
-  }
-  Clear();
-
-  // TODO(1240818): We should probably try to avoid doing this for all
-  // the V8 builtin JS files. It should only happen after running
-  // runtime.js - just like there shouldn't be any fixups left after
-  // that.
-  for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
-    Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
- Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id));
-    JSFunction* function = JSFunction::cast(builtins->GetProperty(*name));
-    builtins->set_javascript_builtin(id, function);
-  }
-
-  return true;
-}
-
-
-void PendingFixups::Clear() {
-  code_.Clear();
-  name_.Clear();
-  pc_.Clear();
-  flags_.Clear();
-}
-
-
-void PendingFixups::Iterate(ObjectVisitor* v) {
-  if (!code_.is_empty()) {
-    v->VisitPointers(&code_[0], &code_[0] + code_.length());
-  }
-}


 class Genesis BASE_EMBEDDED {
@@ -338,6 +228,7 @@
   bool InstallExtension(const char* name);
   bool InstallExtension(v8::RegisteredExtension* current);
   bool InstallSpecialObjects();
+  bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
   bool ConfigureApiObject(Handle<JSObject> object,
                           Handle<ObjectTemplateInfo> object_template);
bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
@@ -379,15 +270,6 @@
   v->Synchronize("NativesCache");
   extensions_cache.Iterate(v);
   v->Synchronize("Extensions");
-  PendingFixups::Iterate(v);
-  v->Synchronize("PendingFixups");
-}
-
-
-// While setting up the environment, we collect code positions that
-// need to be patched before we can run any code in the environment.
-void Bootstrapper::AddFixup(Code* code, MacroAssembler* masm) {
-  PendingFixups::Add(code, masm);
 }


@@ -968,8 +850,7 @@
   Handle<Object> result =
       Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
   if (has_pending_exception) return false;
-  return PendingFixups::Process(
-      Handle<JSBuiltinsObject>(Top::context()->builtins()));
+  return true;
 }


@@ -1176,6 +1057,10 @@
          i < Natives::GetBuiltinsCount();
          i++) {
       if (!CompileBuiltin(i)) return false;
+      // TODO(ager): We really only need to install the JS builtin
+      // functions on the builtins object after compiling and running
+      // runtime.js.
+      if (!InstallJSBuiltins(builtins)) return false;
     }

     // Setup natives with lazy loading.
@@ -1375,6 +1260,22 @@
   current->set_state(v8::INSTALLED);
   return result;
 }
+
+
+bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
+  HandleScope scope;
+  for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
+    Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
+ Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id));
+    Handle<JSFunction> function
+ = Handle<JSFunction>(JSFunction::cast(builtins->GetProperty(*name)));
+    builtins->set_javascript_builtin(id, *function);
+    Handle<SharedFunctionInfo> shared
+        = Handle<SharedFunctionInfo>(function->shared());
+    if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
+  }
+  return true;
+}


 bool Genesis::ConfigureGlobalObjects(
=======================================
--- /branches/bleeding_edge/src/bootstrapper.h  Fri Dec 11 02:40:01 2009
+++ /branches/bleeding_edge/src/bootstrapper.h  Thu Feb 11 00:05:33 2010
@@ -59,9 +59,6 @@
                                  Handle<JSFunction>* handle);
static void NativesCacheAdd(Vector<const char> name, Handle<JSFunction> fun);

-  // Append code that needs fixup at the end of boot strapping.
-  static void AddFixup(Code* code, MacroAssembler* masm);
-
   // Tells whether bootstrapping is active.
   static bool IsActive();

=======================================
--- /branches/bleeding_edge/src/builtins.cc     Tue Feb  9 08:14:14 2010
+++ /branches/bleeding_edge/src/builtins.cc     Thu Feb 11 00:05:33 2010
@@ -168,28 +168,6 @@
// ----------------------------------------------------------------------------


-Handle<Code> Builtins::GetCode(JavaScript id, bool* resolved) {
-  Code* code = Builtins::builtin(Builtins::Illegal);
-  *resolved = false;
-
-  if (Top::context() != NULL) {
-    Object* object = Top::builtins()->javascript_builtin(id);
-    if (object->IsJSFunction()) {
- Handle<SharedFunctionInfo> shared(JSFunction::cast(object)->shared()); - // Make sure the number of parameters match the formal parameter count.
-      ASSERT(shared->formal_parameter_count() ==
-             Builtins::GetArgumentsCount(id));
-      if (EnsureCompiled(shared, CLEAR_EXCEPTION)) {
-        code = shared->code();
-        *resolved = true;
-      }
-    }
-  }
-
-  return Handle<Code>(code);
-}
-
-
 BUILTIN(Illegal) {
   UNREACHABLE();
   return Heap::undefined_value();  // Make compiler happy.
@@ -930,9 +908,6 @@
           v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
         }
       }
-      // Add any unresolved jumps or calls to the fixup list in the
-      // bootstrapper.
-      Bootstrapper::AddFixup(Code::cast(code), &masm);
       // Log the event and add the code to the builtins array.
       LOG(CodeCreateEvent(Logger::BUILTIN_TAG,
                           Code::cast(code), functions[i].s_name));
=======================================
--- /branches/bleeding_edge/src/code-stubs.cc   Wed Feb 10 09:50:16 2010
+++ /branches/bleeding_edge/src/code-stubs.cc   Thu Feb 11 00:05:33 2010
@@ -61,9 +61,6 @@
 void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
   code->set_major_key(MajorKey());

-  // Add unresolved entries in the code to the fixup list.
-  Bootstrapper::AddFixup(code, masm);
-
 #ifdef ENABLE_OPROFILE_AGENT
   // Register the generated stub with the OPROFILE agent.
   OProfileAgent::CreateNativeCodeRegion(GetName(),
=======================================
--- /branches/bleeding_edge/src/codegen.cc      Mon Feb  8 05:44:49 2010
+++ /branches/bleeding_edge/src/codegen.cc      Thu Feb 11 00:05:33 2010
@@ -197,9 +197,6 @@
   Handle<Code> code =
       Factory::NewCode(desc, &sinfo, flags, masm->CodeObject());

-  // Add unresolved entries in the code to the fixup list.
-  Bootstrapper::AddFixup(*code, masm);
-
 #ifdef ENABLE_DISASSEMBLER
   bool print_code = Bootstrapper::IsActive()
       ? FLAG_print_builtin_code
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Tue Feb 9 08:14:14 2010 +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Thu Feb 11 00:05:33 2010
@@ -41,7 +41,6 @@

 MacroAssembler::MacroAssembler(void* buffer, int size)
     : Assembler(buffer, size),
-      unresolved_(0),
       generating_stub_(false),
       allow_stub_calls_(true),
       code_object_(Heap::undefined_value()) {
@@ -1367,9 +1366,6 @@


void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
-
   // Calls are not allowed in some stubs.
   ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());

@@ -1377,55 +1373,22 @@
   // arguments match the expected number of arguments. Fake a
   // parameter count to avoid emitting code to do the check.
   ParameterCount expected(0);
-  InvokeCode(Handle<Code>(code), expected, expected,
-             RelocInfo::CODE_TARGET, flag);
-
-  const char* name = Builtins::GetName(id);
-  int argc = Builtins::GetArgumentsCount(id);
-
-  if (!resolved) {
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(false);
-    Unresolved entry = { pc_offset() - sizeof(int32_t), flags, name };
-    unresolved_.Add(entry);
-  }
+  GetBuiltinEntry(edx, id);
+  InvokeCode(Operand(edx), expected, expected, flag);
 }


void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
-
-  const char* name = Builtins::GetName(id);
-  int argc = Builtins::GetArgumentsCount(id);
-
-  mov(Operand(target), Immediate(code));
-  if (!resolved) {
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(true);
-    Unresolved entry = { pc_offset() - sizeof(int32_t), flags, name };
-    unresolved_.Add(entry);
-  }
-  add(Operand(target), Immediate(Code::kHeaderSize - kHeapObjectTag));
-}
-
-
-Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
-                                            bool* resolved) {
-  // Move the builtin function into the temporary function slot by
-  // reading it from the builtins object. NOTE: We should be able to
-  // reduce this to two instructions by putting the function table in
-  // the global object instead of the "builtins" object and by using a
-  // real register for the function.
-  mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
-  mov(edx, FieldOperand(edx, 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(edx, builtins_offset));
-
-  return Builtins::GetCode(id, resolved);
+  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));
 }


=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Tue Feb 9 08:14:14 2010 +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Thu Feb 11 00:05:33 2010
@@ -390,13 +390,6 @@

   void Move(Register target, Handle<Object> value);

-  struct Unresolved {
-    int pc;
-    uint32_t flags;  // see Bootstrapper::FixupFlags decoders/encoders.
-    const char* name;
-  };
-  List<Unresolved>* unresolved() { return &unresolved_; }
-
   Handle<Object> CodeObject() { return code_object_; }


@@ -441,7 +434,6 @@
Label *on_not_flat_ascii_strings);

  private:
-  List<Unresolved> unresolved_;
   bool generating_stub_;
   bool allow_stub_calls_;
   // This handle will be patched with the code object on installation.
@@ -455,18 +447,6 @@
                       Label* done,
                       InvokeFlag flag);

-  // Prepares for a call or jump to a builtin by doing two things:
- // 1. Emits code that fetches the builtin's function object from the context
-  //    at runtime, and puts it in the register rdi.
-  // 2. Fetches the builtin's code object, and returns it in a handle, at
- // compile time, so that later code can emit instructions to jump or call - // the builtin directly. If the code object has not yet been created, it
-  //    returns the builtin code object for IllegalFunction, and sets the
- // output parameter "resolved" to false. Code that uses the return value - // should then add the address and the builtin name to the list of fixups
-  //    called unresolved_, which is fixed up by the bootstrapper.
-  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
-
   // Activation support.
   void EnterFrame(StackFrame::Type type);
   void LeaveFrame(StackFrame::Type type);
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Mon Feb 8 05:44:49 2010 +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu Feb 11 00:05:33 2010
@@ -39,7 +39,6 @@

 MacroAssembler::MacroAssembler(void* buffer, int size)
     : Assembler(buffer, size),
-      unresolved_(0),
       generating_stub_(false),
       allow_stub_calls_(true),
       code_object_(Heap::undefined_value()) {
@@ -415,38 +414,30 @@
 }


-void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
-
-  const char* name = Builtins::GetName(id);
-  int argc = Builtins::GetArgumentsCount(id);
-
-  movq(target, code, RelocInfo::EMBEDDED_OBJECT);
-  if (!resolved) {
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(true);
-    Unresolved entry = { pc_offset() - sizeof(intptr_t), flags, name };
-    unresolved_.Add(entry);
-  }
-  addq(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
+void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
+  // Calls are not allowed in some stubs.
+  ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
+
+  // Rely on the assertion to check that the number of provided
+  // arguments match the expected number of arguments. Fake a
+  // parameter count to avoid emitting code to do the check.
+  ParameterCount expected(0);
+  GetBuiltinEntry(rdx, id);
+  InvokeCode(rdx, expected, expected, flag);
 }

-Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
-                                            bool* resolved) {
-  // Move the builtin function into the temporary function slot by
-  // reading it from the builtins object. NOTE: We should be able to
-  // reduce this to two instructions by putting the function table in
-  // the global object instead of the "builtins" object and by using a
-  // real register for the function.
-  movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
-  movq(rdx, FieldOperand(rdx, GlobalObject::kBuiltinsOffset));
+
+void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
+  // 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(rdx, builtins_offset));
-
-  return Builtins::GetCode(id, resolved);
+  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));
 }


@@ -1784,38 +1775,6 @@
 #endif  // ENABLE_DEBUGGER_SUPPORT


-void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
-  bool resolved;
-  Handle<Code> code = ResolveBuiltin(id, &resolved);
-
-  // Calls are not allowed in some stubs.
-  ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
-
-  // Rely on the assertion to check that the number of provided
-  // arguments match the expected number of arguments. Fake a
-  // parameter count to avoid emitting code to do the check.
-  ParameterCount expected(0);
-  InvokeCode(Handle<Code>(code),
-             expected,
-             expected,
-             RelocInfo::CODE_TARGET,
-             flag);
-
-  const char* name = Builtins::GetName(id);
-  int argc = Builtins::GetArgumentsCount(id);
-  // The target address for the jump is stored as an immediate at offset
-  // kInvokeCodeAddressOffset.
-  if (!resolved) {
-    uint32_t flags =
-        Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
-        Bootstrapper::FixupFlagsUseCodeObject::encode(false);
-    Unresolved entry =
-        { pc_offset() - kCallTargetAddressOffset, flags, name };
-    unresolved_.Add(entry);
-  }
-}
-
-
 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
                                     const ParameterCount& actual,
                                     Handle<Code> code_constant,
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Mon Feb 8 05:44:49 2010 +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Thu Feb 11 00:05:33 2010
@@ -680,13 +680,6 @@

   void Ret();

-  struct Unresolved {
-    int pc;
-    uint32_t flags;  // see Bootstrapper::FixupFlags decoders/encoders.
-    const char* name;
-  };
-  List<Unresolved>* unresolved() { return &unresolved_; }
-
   Handle<Object> CodeObject() { return code_object_; }


@@ -718,7 +711,6 @@
   bool allow_stub_calls() { return allow_stub_calls_; }

  private:
-  List<Unresolved> unresolved_;
   bool generating_stub_;
   bool allow_stub_calls_;
   // This handle will be patched with the code object on installation.
@@ -732,18 +724,6 @@
                       Label* done,
                       InvokeFlag flag);

-  // Prepares for a call or jump to a builtin by doing two things:
- // 1. Emits code that fetches the builtin's function object from the context
-  //    at runtime, and puts it in the register rdi.
-  // 2. Fetches the builtin's code object, and returns it in a handle, at
- // compile time, so that later code can emit instructions to jump or call - // the builtin directly. If the code object has not yet been created, it
-  //    returns the builtin code object for IllegalFunction, and sets the
- // output parameter "resolved" to false. Code that uses the return value - // should then add the address and the builtin name to the list of fixups
-  //    called unresolved_, which is fixed up by the bootstrapper.
-  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
-
   // Activation support.
   void EnterFrame(StackFrame::Type type);
   void LeaveFrame(StackFrame::Type type);

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to