Revision: 5451
Author: [email protected]
Date: Tue Sep 14 07:52:53 2010
Log: Move inlined function declarations and support from codegen.* to runtime.*.
Review URL: http://codereview.chromium.org/3293002
http://code.google.com/p/v8/source/detail?r=5451

Modified:
 /branches/bleeding_edge/src/arm/codegen-arm.h
 /branches/bleeding_edge/src/codegen.cc
 /branches/bleeding_edge/src/codegen.h
 /branches/bleeding_edge/src/full-codegen.cc
 /branches/bleeding_edge/src/full-codegen.h
 /branches/bleeding_edge/src/handles.cc
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/ia32/codegen-ia32.h
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/src/x64/codegen-x64.h

=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.h       Wed Sep  1 06:13:31 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.h       Tue Sep 14 07:52:53 2010
@@ -270,10 +270,6 @@
   }

   void AddDeferred(DeferredCode* code) { deferred_.Add(code); }
-
-  // If the name is an inline runtime function call return the number of
-  // expected arguments. Otherwise return -1.
-  static int InlineRuntimeCallArgumentsCount(Handle<String> name);

   // Constants related to patching of inlined load/store.
   static int GetInlinedKeyedLoadInstructionsAfterPatch() {
@@ -290,6 +286,12 @@
   }

  private:
+ // Type of a member function that generates inline code for a native function.
+  typedef void (CodeGenerator::*InlineFunctionGenerator)
+      (ZoneList<Expression*>*);
+
+  static const InlineFunctionGenerator kInlineFunctionGenerators[];
+
   // Construction/Destruction
   explicit CodeGenerator(MacroAssembler* masm);

@@ -447,13 +449,9 @@
   void Branch(bool if_true, JumpTarget* target);
   void CheckStack();

-  struct InlineRuntimeLUT {
-    void (CodeGenerator::*method)(ZoneList<Expression*>*);
-    const char* name;
-    int nargs;
-  };
-
-  static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
+  static InlineFunctionGenerator FindInlineFunctionGenerator(
+      Runtime::FunctionId function_id);
+
   bool CheckForInlineRuntimeCall(CallRuntime* node);

   static Handle<Code> ComputeLazyCompile(int argc);
@@ -599,8 +597,6 @@
   // Size of inlined write barriers generated by EmitNamedStore.
   static int inlined_write_barrier_size_;

-  static InlineRuntimeLUT kInlineRuntimeLUT[];
-
   friend class VirtualFrame;
   friend class JumpTarget;
   friend class Reference;
=======================================
--- /branches/bleeding_edge/src/codegen.cc      Wed Sep  1 06:13:31 2010
+++ /branches/bleeding_edge/src/codegen.cc      Tue Sep 14 07:52:53 2010
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -344,53 +344,40 @@
 }


-// List of special runtime calls which are generated inline. For some of these -// functions the code will be generated inline, and for others a call to a code
-// stub will be inlined.
-
-#define INLINE_RUNTIME_ENTRY(Name, argc, ressize) \ - {&CodeGenerator::Generate##Name, "_" #Name, argc}, \
-
-CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = {
-  INLINE_RUNTIME_FUNCTION_LIST(INLINE_RUNTIME_ENTRY)
+// Lookup table for code generators for special runtime calls which are
+// generated inline.
+#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize)          \
+    &CodeGenerator::Generate##Name,
+
+const CodeGenerator::InlineFunctionGenerator
+    CodeGenerator::kInlineFunctionGenerators[] = {
+        INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
+        INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
 };
-
-#undef INLINE_RUNTIME_ENTRY
-
-CodeGenerator::InlineRuntimeLUT* CodeGenerator::FindInlineRuntimeLUT(
-    Handle<String> name) {
-  const int entries_count =
-      sizeof(kInlineRuntimeLUT) / sizeof(InlineRuntimeLUT);
-  for (int i = 0; i < entries_count; i++) {
-    InlineRuntimeLUT* entry = &kInlineRuntimeLUT[i];
-    if (name->IsEqualTo(CStrVector(entry->name))) {
-      return entry;
-    }
-  }
-  return NULL;
+#undef INLINE_FUNCTION_GENERATOR_ADDRESS
+
+
+CodeGenerator::InlineFunctionGenerator
+  CodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) {
+    return kInlineFunctionGenerators[
+ static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction)];
 }


 bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) {
   ZoneList<Expression*>* args = node->arguments();
   Handle<String> name = node->name();
-  if (name->length() > 0 && name->Get(0) == '_') {
-    InlineRuntimeLUT* entry = FindInlineRuntimeLUT(name);
-    if (entry != NULL) {
-      ((*this).*(entry->method))(args);
+  Runtime::Function* function = node->function();
+  if (function != NULL && function->intrinsic_type == Runtime::INLINE) {
+    InlineFunctionGenerator generator =
+        FindInlineFunctionGenerator(function->function_id);
+    if (generator != NULL) {
+      ((*this).*(generator))(args);
       return true;
     }
   }
   return false;
 }
-
-
-int CodeGenerator::InlineRuntimeCallArgumentsCount(Handle<String> name) {
-  CodeGenerator::InlineRuntimeLUT* f =
-      CodeGenerator::FindInlineRuntimeLUT(name);
-  if (f != NULL) return f->nargs;
-  return -1;
-}


 // Simple condition analysis.  ALWAYS_TRUE and ALWAYS_FALSE represent a
=======================================
--- /branches/bleeding_edge/src/codegen.h       Wed Sep  1 06:13:31 2010
+++ /branches/bleeding_edge/src/codegen.h       Tue Sep 14 07:52:53 2010
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -71,48 +71,6 @@
 //   CodeForDoWhileConditionPosition
 //   CodeForSourcePosition

-
-#define INLINE_RUNTIME_FUNCTION_LIST(F) \
- F(IsSmi, 1, 1) \ - F(IsNonNegativeSmi, 1, 1) \ - F(IsArray, 1, 1) \ - F(IsRegExp, 1, 1) \ - F(CallFunction, -1 /* receiver + n args + function */, 1) \ - F(IsConstructCall, 0, 1) \ - F(ArgumentsLength, 0, 1) \ - F(Arguments, 1, 1) \ - F(ClassOf, 1, 1) \ - F(ValueOf, 1, 1) \ - F(SetValueOf, 2, 1) \ - F(StringCharCodeAt, 2, 1) \ - F(StringCharFromCode, 1, 1) \ - F(StringCharAt, 2, 1) \ - F(ObjectEquals, 2, 1) \ - F(Log, 3, 1) \ - F(RandomHeapNumber, 0, 1) \ - F(IsObject, 1, 1) \ - F(IsFunction, 1, 1) \ - F(IsUndetectableObject, 1, 1) \ - F(IsSpecObject, 1, 1) \ - F(IsStringWrapperSafeForDefaultValueOf, 1, 1) \ - F(StringAdd, 2, 1) \ - F(SubString, 3, 1) \ - F(StringCompare, 2, 1) \ - F(RegExpExec, 4, 1) \ - F(RegExpConstructResult, 3, 1) \ - F(RegExpCloneResult, 1, 1) \ - F(GetFromCache, 2, 1) \ - F(NumberToString, 1, 1) \ - F(SwapElements, 3, 1) \ - F(MathPow, 2, 1) \ - F(MathSin, 1, 1) \ - F(MathCos, 1, 1) \ - F(MathSqrt, 1, 1) \ - F(IsRegExpEquivalent, 2, 1) \ - F(HasCachedArrayIndex, 1, 1) \
-  F(GetCachedArrayIndex, 1, 1)
-
-
 #if V8_TARGET_ARCH_IA32
 #include "ia32/codegen-ia32.h"
 #elif V8_TARGET_ARCH_X64
=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Thu Sep  9 03:44:24 2010
+++ /branches/bleeding_edge/src/full-codegen.cc Tue Sep 14 07:52:53 2010
@@ -505,18 +505,36 @@
 }


-void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
-  Handle<String> name = expr->name();
-  SmartPointer<char> cstring = name->ToCString();
-
-#define CHECK_EMIT_INLINE_CALL(name, x, y) \
-  if (strcmp("_"#name, *cstring) == 0) {   \
-    Emit##name(expr->arguments());         \
-    return;                                \
-  }
-  INLINE_RUNTIME_FUNCTION_LIST(CHECK_EMIT_INLINE_CALL)
-#undef CHECK_EMIT_INLINE_CALL
-  UNREACHABLE();
+// Lookup table for code generators for  special runtime calls which are
+// generated inline.
+#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize)          \
+    &FullCodeGenerator::Emit##Name,
+
+const FullCodeGenerator::InlineFunctionGenerator
+  FullCodeGenerator::kInlineFunctionGenerators[] = {
+    INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
+    INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
+  };
+#undef INLINE_FUNCTION_GENERATOR_ADDRESS
+
+
+FullCodeGenerator::InlineFunctionGenerator
+  FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) {
+    return kInlineFunctionGenerators[
+ static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction)];
+}
+
+
+void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* node) {
+  ZoneList<Expression*>* args = node->arguments();
+  Handle<String> name = node->name();
+  Runtime::Function* function = node->function();
+  ASSERT(function != NULL);
+  ASSERT(function->intrinsic_type == Runtime::INLINE);
+  InlineFunctionGenerator generator =
+      FindInlineFunctionGenerator(function->function_id);
+  ASSERT(generator != NULL);
+  ((*this).*(generator))(args);
 }


=======================================
--- /branches/bleeding_edge/src/full-codegen.h  Fri Sep 10 03:57:07 2010
+++ /branches/bleeding_edge/src/full-codegen.h  Tue Sep 14 07:52:53 2010
@@ -243,6 +243,12 @@
     kRightConstant
   };

+ // Type of a member function that generates inline code for a native function.
+  typedef void (FullCodeGenerator::*InlineFunctionGenerator)
+      (ZoneList<Expression*>*);
+
+  static const InlineFunctionGenerator kInlineFunctionGenerators[];
+
   // Compute the frame pointer relative offset for a given local or
   // parameter slot.
   int SlotOffset(Slot* slot);
@@ -373,10 +379,13 @@
void EmitKeyedCallWithIC(Call* expr, Expression* key, RelocInfo::Mode mode);

   // Platform-specific code for inline runtime calls.
+ InlineFunctionGenerator FindInlineFunctionGenerator(Runtime::FunctionId id);
+
   void EmitInlineRuntimeCall(CallRuntime* expr);

 #define EMIT_INLINE_RUNTIME_CALL(name, x, y) \
   void Emit##name(ZoneList<Expression*>* arguments);
+  INLINE_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL)
   INLINE_RUNTIME_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL)
 #undef EMIT_INLINE_RUNTIME_CALL

=======================================
--- /branches/bleeding_edge/src/handles.cc      Tue Aug 17 04:44:01 2010
+++ /branches/bleeding_edge/src/handles.cc      Tue Sep 14 07:52:53 2010
@@ -31,7 +31,6 @@
 #include "api.h"
 #include "arguments.h"
 #include "bootstrapper.h"
-#include "codegen.h"
 #include "compiler.h"
 #include "debug.h"
 #include "execution.h"
=======================================
--- /branches/bleeding_edge/src/heap.cc Mon Aug 30 05:34:32 2010
+++ /branches/bleeding_edge/src/heap.cc Tue Sep 14 07:52:53 2010
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -1834,6 +1834,13 @@

   CreateFixedStubs();

+  // Allocate the dictionary of intrinsic function names.
+  obj = StringDictionary::Allocate(Runtime::kNumFunctions);
+  if (obj->IsFailure()) return false;
+  obj = Runtime::InitializeIntrinsicFunctionNames(obj);
+  if (obj->IsFailure()) return false;
+  set_intrinsic_function_names(StringDictionary::cast(obj));
+
   if (InitializeNumberStringCache()->IsFailure()) return false;

   // Allocate cache for single character ASCII strings.
=======================================
--- /branches/bleeding_edge/src/heap.h  Tue Aug 31 01:05:42 2010
+++ /branches/bleeding_edge/src/heap.h  Tue Sep 14 07:52:53 2010
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -114,6 +114,7 @@
V(Object, last_script_id, LastScriptId) \ V(Script, empty_script, EmptyScript) \ V(Smi, real_stack_limit, RealStackLimit) \ + V(StringDictionary, intrinsic_function_names, IntrinsicFunctionNames) \

 #if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
#define STRONG_ROOT_LIST(V) \
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.h     Wed Sep  1 06:13:31 2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.h     Tue Sep 14 07:52:53 2010
@@ -344,10 +344,6 @@

   bool in_spilled_code() const { return in_spilled_code_; }
   void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; }
-
-  // If the name is an inline runtime function call return the number of
-  // expected arguments. Otherwise return -1.
-  static int InlineRuntimeCallArgumentsCount(Handle<String> name);

// Return a position of the element at |index_as_smi| + | additional_offset| // in FixedArray pointer to which is held in |array|. |index_as_smi| is Smi.
@@ -363,6 +359,12 @@
   }

  private:
+ // Type of a member function that generates inline code for a native function.
+  typedef void (CodeGenerator::*InlineFunctionGenerator)
+      (ZoneList<Expression*>*);
+
+  static const InlineFunctionGenerator kInlineFunctionGenerators[];
+
   // Construction/Destruction
   explicit CodeGenerator(MacroAssembler* masm);

@@ -624,13 +626,9 @@

   void CheckStack();

-  struct InlineRuntimeLUT {
-    void (CodeGenerator::*method)(ZoneList<Expression*>*);
-    const char* name;
-    int nargs;
-  };
-
-  static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
+  static InlineFunctionGenerator FindInlineFunctionGenerator(
+      Runtime::FunctionId function_id);
+
   bool CheckForInlineRuntimeCall(CallRuntime* node);

   void ProcessDeclarations(ZoneList<Declaration*>* declarations);
@@ -792,8 +790,6 @@
   // in a spilled state.
   bool in_spilled_code_;

-  static InlineRuntimeLUT kInlineRuntimeLUT[];
-
   friend class VirtualFrame;
   friend class JumpTarget;
   friend class Reference;
=======================================
--- /branches/bleeding_edge/src/parser.cc       Thu Sep  9 04:49:21 2010
+++ /branches/bleeding_edge/src/parser.cc       Tue Sep 14 07:52:53 2010
@@ -4243,58 +4243,43 @@

   Expect(Token::MOD, CHECK_OK);
   Handle<String> name = ParseIdentifier(CHECK_OK);
-  Runtime::Function* function =
-      Runtime::FunctionForName(scanner_.literal());
   ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
-  if (function == NULL && extension_ != NULL) {
+  if (is_pre_parsing_) return NULL;
+
+  if (extension_ != NULL) {
     // The extension structures are only accessible while parsing the
     // very first time not when reparsing because of lazy compilation.
     top_scope_->ForceEagerCompilation();
   }

-  // Check for built-in macros.
-  if (!is_pre_parsing_) {
-    if (function == Runtime::FunctionForId(Runtime::kIS_VAR)) {
-      // %IS_VAR(x)
-      //   evaluates to x if x is a variable,
-      //   leads to a parse error otherwise
-      if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
-        return args->at(0);
-      }
-      *ok = false;
-    // Check here for other macros.
-    // } else if (function == Runtime::FunctionForId(Runtime::kIS_VAR)) {
-    //   ...
-    }
-
-    if (!*ok) {
-      // We found a macro but it failed.
+  Runtime::Function* function = Runtime::FunctionForSymbol(name);
+
+  // Check for built-in IS_VAR macro.
+  if (function != NULL &&
+      function->intrinsic_type == Runtime::RUNTIME &&
+      function->function_id == Runtime::kIS_VAR) {
+    // %IS_VAR(x) evaluates to x if x is a variable,
+    // leads to a parse error otherwise.  Could be implemented as an
+    // inline function %_IS_VAR(x) to eliminate this special case.
+    if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
+      return args->at(0);
+    } else {
       ReportMessage("unable_to_parse", Vector<const char*>::empty());
+      *ok = false;
       return NULL;
     }
   }

- // Check that the expected number arguments are passed to runtime functions.
-  if (!is_pre_parsing_) {
-    if (function != NULL
-        && function->nargs != -1
-        && function->nargs != args->length()) {
-      ReportMessage("illegal_access", Vector<const char*>::empty());
-      *ok = false;
-      return NULL;
-    } else if (function == NULL && !name.is_null()) {
- // If this is not a runtime function implemented in C++ it might be an
-      // inlined runtime function.
-      int argc = CodeGenerator::InlineRuntimeCallArgumentsCount(name);
-      if (argc != -1 && argc != args->length()) {
-        ReportMessage("illegal_access", Vector<const char*>::empty());
-        *ok = false;
-        return NULL;
-      }
-    }
+  // Check that the expected number of arguments are being passed.
+  if (function != NULL &&
+      function->nargs != -1 &&
+      function->nargs != args->length()) {
+    ReportMessage("illegal_access", Vector<const char*>::empty());
+    *ok = false;
+    return NULL;
   }

-  // Otherwise we have a valid runtime call.
+  // We have a valid intrinsics call or a call to a builtin.
   return NEW(CallRuntime(name, function, args));
 }

=======================================
--- /branches/bleeding_edge/src/runtime.cc      Fri Sep 10 02:22:41 2010
+++ /branches/bleeding_edge/src/runtime.cc      Tue Sep 14 07:52:53 2010
@@ -4519,7 +4519,6 @@
   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
   double value = StringToInt(s, radix);
   return Heap::NumberFromDouble(value);
-  return Heap::nan_value();
 }


@@ -10064,6 +10063,7 @@
   inline_runtime_functions = false;
   RUNTIME_FUNCTION_LIST(ADD_ENTRY)
   inline_runtime_functions = true;
+  INLINE_FUNCTION_LIST(ADD_ENTRY)
   INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY)
 #undef ADD_ENTRY
   return *result;
@@ -10090,33 +10090,56 @@
// ----------------------------------------------------------------------------
 // Implementation of Runtime

-#define F(name, nargs, ressize)                                           \
-  { #name, FUNCTION_ADDR(Runtime_##name), nargs, \
-    static_cast<int>(Runtime::k##name), ressize },
-
-static Runtime::Function Runtime_functions[] = {
+#define F(name, number_of_args, result_size)                             \
+  { Runtime::k##name, Runtime::RUNTIME, #name,   \
+    FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
+
+
+#define I(name, number_of_args, result_size)                             \
+  { Runtime::kInline##name, Runtime::INLINE,     \
+    "_" #name, NULL, number_of_args, result_size },
+
+Runtime::Function kIntrinsicFunctions[] = {
   RUNTIME_FUNCTION_LIST(F)
-  { NULL, NULL, 0, -1, 0 }
+  INLINE_FUNCTION_LIST(I)
+  INLINE_RUNTIME_FUNCTION_LIST(I)
 };

-#undef F
-
-
-Runtime::Function* Runtime::FunctionForId(FunctionId fid) {
-  ASSERT(0 <= fid && fid < kNofFunctions);
-  return &Runtime_functions[fid];
+
+const int Runtime::kNotFound;
+
+
+Object* Runtime::InitializeIntrinsicFunctionNames(Object* dictionary) {
+  ASSERT(dictionary != NULL);
+  ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0);
+  for (int i = 0; i < kNumFunctions; ++i) {
+ Object* name_symbol = Heap::LookupAsciiSymbol(kIntrinsicFunctions[i].name);
+    if (name_symbol->IsFailure()) return name_symbol;
+ StringDictionary* string_dictionary = StringDictionary::cast(dictionary);
+    dictionary = string_dictionary->Add(String::cast(name_symbol),
+                                        Smi::FromInt(i),
+                                        PropertyDetails(NONE, NORMAL));
+ // Non-recoverable failure. Calling code must restart heap initialization.
+    if (dictionary->IsFailure()) return dictionary;
+  }
+  return dictionary;
 }


-Runtime::Function* Runtime::FunctionForName(Vector<const char> name) {
-  for (Function* f = Runtime_functions; f->name != NULL; f++) {
-    if (strncmp(f->name, name.start(), name.length()) == 0
-        && f->name[name.length()] == 0) {
-      return f;
-    }
+Runtime::Function* Runtime::FunctionForSymbol(Handle<String> name) {
+  int entry = Heap::intrinsic_function_names()->FindEntry(*name);
+  if (entry != kNotFound) {
+    Object* smi_index = Heap::intrinsic_function_names()->ValueAt(entry);
+    int function_index = Smi::cast(smi_index)->value();
+    return &(kIntrinsicFunctions[function_index]);
   }
   return NULL;
 }
+
+
+Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
+  return &(kIntrinsicFunctions[static_cast<int>(id)]);
+}


 void Runtime::PerformGC(Object* result) {
=======================================
--- /branches/bleeding_edge/src/runtime.h       Thu Aug 26 06:59:37 2010
+++ /branches/bleeding_edge/src/runtime.h       Tue Sep 14 07:52:53 2010
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -389,6 +389,59 @@
   RUNTIME_FUNCTION_LIST_PROFILER_SUPPORT(F)

// ----------------------------------------------------------------------------
+// INLINE_FUNCTION_LIST defines all inlined functions accessed
+// with a native call of the form %_name from within JS code.
+// Entries have the form F(name, number of arguments, number of return values).
+#define INLINE_FUNCTION_LIST(F) \
+ F(IsSmi, 1, 1) \ + F(IsNonNegativeSmi, 1, 1) \ + F(IsArray, 1, 1) \ + F(IsRegExp, 1, 1) \ + F(CallFunction, -1 /* receiver + n args + function */, 1) \ + F(ArgumentsLength, 0, 1) \ + F(Arguments, 1, 1) \ + F(ValueOf, 1, 1) \ + F(SetValueOf, 2, 1) \ + F(StringCharFromCode, 1, 1) \ + F(StringCharAt, 2, 1) \ + F(ObjectEquals, 2, 1) \ + F(RandomHeapNumber, 0, 1) \ + F(IsObject, 1, 1) \ + F(IsFunction, 1, 1) \ + F(IsUndetectableObject, 1, 1) \ + F(IsSpecObject, 1, 1) \ + F(IsStringWrapperSafeForDefaultValueOf, 1, 1) \ + F(MathPow, 2, 1) \ + F(MathSin, 1, 1) \ + F(MathCos, 1, 1) \ + F(MathSqrt, 1, 1) \ + F(IsRegExpEquivalent, 2, 1) \ + F(HasCachedArrayIndex, 1, 1) \
+  F(GetCachedArrayIndex, 1, 1)
+
+
+// ----------------------------------------------------------------------------
+// INLINE_AND_RUNTIME_FUNCTION_LIST defines all inlined functions accessed
+// with a native call of the form %_name from within JS code that also have
+  // a corresponding runtime function, that is called for slow cases.
+// Entries have the form F(name, number of arguments, number of return values).
+#define INLINE_RUNTIME_FUNCTION_LIST(F) \
+ F(IsConstructCall, 0, 1) \ + F(ClassOf, 1, 1) \ + F(StringCharCodeAt, 2, 1) \ + F(Log, 3, 1) \ + F(StringAdd, 2, 1) \ + F(SubString, 3, 1) \ + F(StringCompare, 2, 1) \ + F(RegExpExec, 4, 1) \ + F(RegExpConstructResult, 3, 1) \ + F(RegExpCloneResult, 1, 1) \ + F(GetFromCache, 2, 1) \ + F(NumberToString, 1, 1) \
+  F(SwapElements, 3, 1)
+
+
+//---------------------------------------------------------------------------
 // Runtime provides access to all C++ runtime functions.

 class Runtime : public AllStatic {
@@ -396,33 +449,52 @@
   enum FunctionId {
 #define F(name, nargs, ressize) k##name,
     RUNTIME_FUNCTION_LIST(F)
-    kNofFunctions
 #undef F
+#define F(name, nargs, ressize) kInline##name,
+    INLINE_FUNCTION_LIST(F)
+    INLINE_RUNTIME_FUNCTION_LIST(F)
+#undef F
+    kNumFunctions,
+    kFirstInlineFunction = kInlineIsSmi
   };

-  // Runtime function descriptor.
+  enum IntrinsicType {
+    RUNTIME,
+    INLINE
+  };
+
+  // Intrinsic function descriptor.
   struct Function {
+    FunctionId function_id;
+    IntrinsicType intrinsic_type;
     // The JS name of the function.
     const char* name;

-    // The C++ (native) entry point.
+    // The C++ (native) entry point.  NULL if the function is inlined.
     byte* entry;

-    // The number of arguments expected; nargs < 0 if variable no. of
-    // arguments.
+    // The number of arguments expected. nargs is -1 if the function takes
+    // a variable number of arguments.
     int nargs;
-    int stub_id;
-    // Size of result, if complex (larger than a single pointer),
-    // otherwise zero.
+    // Size of result.  Most functions return a single pointer, size 1.
     int result_size;
   };

-  // Get the runtime function with the given function id.
-  static Function* FunctionForId(FunctionId fid);
-
-  // Get the runtime function with the given name.
-  static Function* FunctionForName(Vector<const char> name);
-
+  static const int kNotFound = -1;
+
+ // Add symbols for all the intrinsic function names to a StringDictionary.
+  // Returns failure if an allocation fails.  In this case, it must be
+  // retried with a new, empty StringDictionary, not with the same one.
+  // Alternatively, heap initialization can be completely restarted.
+  static Object* InitializeIntrinsicFunctionNames(Object* dictionary);
+
+ // Get the intrinsic function with the given name, which must be a symbol.
+  static Function* FunctionForSymbol(Handle<String> name);
+
+  // Get the intrinsic function with the given FunctionId.
+  static Function* FunctionForId(FunctionId id);
+
+  // General-purpose helper functions for runtime system.
static int StringMatch(Handle<String> sub, Handle<String> pat, int index);

   static bool IsUpperCaseChar(uint16_t ch);
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.h       Wed Sep  1 06:13:31 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.h       Tue Sep 14 07:52:53 2010
@@ -342,16 +342,18 @@

   bool in_spilled_code() const { return in_spilled_code_; }
   void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; }
-
-  // If the name is an inline runtime function call return the number of
-  // expected arguments. Otherwise return -1.
-  static int InlineRuntimeCallArgumentsCount(Handle<String> name);

   static Operand ContextOperand(Register context, int index) {
     return Operand(context, Context::SlotOffset(index));
   }

  private:
+ // Type of a member function that generates inline code for a native function.
+  typedef void (CodeGenerator::*InlineFunctionGenerator)
+      (ZoneList<Expression*>*);
+
+  static const InlineFunctionGenerator kInlineFunctionGenerators[];
+
   // Construction/Destruction
   explicit CodeGenerator(MacroAssembler* masm);

@@ -584,12 +586,9 @@

   void CheckStack();

-  struct InlineRuntimeLUT {
-    void (CodeGenerator::*method)(ZoneList<Expression*>*);
-    const char* name;
-    int nargs;
-  };
-  static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
+  static InlineFunctionGenerator FindInlineFunctionGenerator(
+      Runtime::FunctionId function_id);
+
   bool CheckForInlineRuntimeCall(CallRuntime* node);

   void ProcessDeclarations(ZoneList<Declaration*>* declarations);
@@ -742,8 +741,6 @@
   // in a spilled state.
   bool in_spilled_code_;

-  static InlineRuntimeLUT kInlineRuntimeLUT[];
-
   friend class VirtualFrame;
   friend class JumpTarget;
   friend class Reference;

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

Reply via email to