OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 4501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4512 NoHandleAllocation ha; | 4512 NoHandleAllocation ha; |
4513 | 4513 |
4514 CONVERT_CHECKED(String, s, args[0]); | 4514 CONVERT_CHECKED(String, s, args[0]); |
4515 CONVERT_SMI_CHECKED(radix, args[1]); | 4515 CONVERT_SMI_CHECKED(radix, args[1]); |
4516 | 4516 |
4517 s->TryFlatten(); | 4517 s->TryFlatten(); |
4518 | 4518 |
4519 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); | 4519 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); |
4520 double value = StringToInt(s, radix); | 4520 double value = StringToInt(s, radix); |
4521 return Heap::NumberFromDouble(value); | 4521 return Heap::NumberFromDouble(value); |
4522 return Heap::nan_value(); | |
4523 } | 4522 } |
4524 | 4523 |
4525 | 4524 |
4526 static Object* Runtime_StringParseFloat(Arguments args) { | 4525 static Object* Runtime_StringParseFloat(Arguments args) { |
4527 NoHandleAllocation ha; | 4526 NoHandleAllocation ha; |
4528 CONVERT_CHECKED(String, str, args[0]); | 4527 CONVERT_CHECKED(String, str, args[0]); |
4529 | 4528 |
4530 // ECMA-262 section 15.1.2.3, empty string is NaN | 4529 // ECMA-262 section 15.1.2.3, empty string is NaN |
4531 double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value()); | 4530 double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value()); |
4532 | 4531 |
(...skipping 5524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10057 Vector<const char>(#Name, StrLength(#Name))); \ | 10056 Vector<const char>(#Name, StrLength(#Name))); \ |
10058 } \ | 10057 } \ |
10059 Handle<JSArray> pair = Factory::NewJSArray(0); \ | 10058 Handle<JSArray> pair = Factory::NewJSArray(0); \ |
10060 SetElement(pair, 0, name); \ | 10059 SetElement(pair, 0, name); \ |
10061 SetElement(pair, 1, Handle<Smi>(Smi::FromInt(argc))); \ | 10060 SetElement(pair, 1, Handle<Smi>(Smi::FromInt(argc))); \ |
10062 SetElement(result, index++, pair); \ | 10061 SetElement(result, index++, pair); \ |
10063 } | 10062 } |
10064 inline_runtime_functions = false; | 10063 inline_runtime_functions = false; |
10065 RUNTIME_FUNCTION_LIST(ADD_ENTRY) | 10064 RUNTIME_FUNCTION_LIST(ADD_ENTRY) |
10066 inline_runtime_functions = true; | 10065 inline_runtime_functions = true; |
| 10066 INLINE_FUNCTION_LIST(ADD_ENTRY) |
10067 INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY) | 10067 INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY) |
10068 #undef ADD_ENTRY | 10068 #undef ADD_ENTRY |
10069 return *result; | 10069 return *result; |
10070 } | 10070 } |
10071 #endif | 10071 #endif |
10072 | 10072 |
10073 | 10073 |
10074 static Object* Runtime_Log(Arguments args) { | 10074 static Object* Runtime_Log(Arguments args) { |
10075 ASSERT(args.length() == 2); | 10075 ASSERT(args.length() == 2); |
10076 CONVERT_CHECKED(String, format, args[0]); | 10076 CONVERT_CHECKED(String, format, args[0]); |
10077 CONVERT_CHECKED(JSArray, elms, args[1]); | 10077 CONVERT_CHECKED(JSArray, elms, args[1]); |
10078 Vector<const char> chars = format->ToAsciiVector(); | 10078 Vector<const char> chars = format->ToAsciiVector(); |
10079 Logger::LogRuntime(chars, elms); | 10079 Logger::LogRuntime(chars, elms); |
10080 return Heap::undefined_value(); | 10080 return Heap::undefined_value(); |
10081 } | 10081 } |
10082 | 10082 |
10083 | 10083 |
10084 static Object* Runtime_IS_VAR(Arguments args) { | 10084 static Object* Runtime_IS_VAR(Arguments args) { |
10085 UNREACHABLE(); // implemented as macro in the parser | 10085 UNREACHABLE(); // implemented as macro in the parser |
10086 return NULL; | 10086 return NULL; |
10087 } | 10087 } |
10088 | 10088 |
10089 | 10089 |
10090 // ---------------------------------------------------------------------------- | 10090 // ---------------------------------------------------------------------------- |
10091 // Implementation of Runtime | 10091 // Implementation of Runtime |
10092 | 10092 |
10093 #define F(name, nargs, ressize) \ | 10093 #define F(name, number_of_args, result_size) \ |
10094 { #name, FUNCTION_ADDR(Runtime_##name), nargs, \ | 10094 { Runtime::k##name, Runtime::RUNTIME, #name, \ |
10095 static_cast<int>(Runtime::k##name), ressize }, | 10095 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, |
10096 | 10096 |
10097 static Runtime::Function Runtime_functions[] = { | 10097 |
| 10098 #define I(name, number_of_args, result_size) \ |
| 10099 { Runtime::kInline##name, Runtime::INLINE, \ |
| 10100 "_" #name, NULL, number_of_args, result_size }, |
| 10101 |
| 10102 Runtime::Function kIntrinsicFunctions[] = { |
10098 RUNTIME_FUNCTION_LIST(F) | 10103 RUNTIME_FUNCTION_LIST(F) |
10099 { NULL, NULL, 0, -1, 0 } | 10104 INLINE_FUNCTION_LIST(I) |
| 10105 INLINE_RUNTIME_FUNCTION_LIST(I) |
10100 }; | 10106 }; |
10101 | 10107 |
10102 #undef F | 10108 |
| 10109 const int Runtime::kNotFound; |
10103 | 10110 |
10104 | 10111 |
10105 Runtime::Function* Runtime::FunctionForId(FunctionId fid) { | 10112 Object* Runtime::InitializeIntrinsicFunctionNames(Object* dictionary) { |
10106 ASSERT(0 <= fid && fid < kNofFunctions); | 10113 ASSERT(dictionary != NULL); |
10107 return &Runtime_functions[fid]; | 10114 ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0); |
| 10115 for (int i = 0; i < kNumFunctions; ++i) { |
| 10116 Object* name_symbol = Heap::LookupAsciiSymbol(kIntrinsicFunctions[i].name); |
| 10117 if (name_symbol->IsFailure()) return name_symbol; |
| 10118 StringDictionary* string_dictionary = StringDictionary::cast(dictionary); |
| 10119 dictionary = string_dictionary->Add(String::cast(name_symbol), |
| 10120 Smi::FromInt(i), |
| 10121 PropertyDetails(NONE, NORMAL)); |
| 10122 // Non-recoverable failure. Calling code must restart heap initialization. |
| 10123 if (dictionary->IsFailure()) return dictionary; |
| 10124 } |
| 10125 return dictionary; |
10108 } | 10126 } |
10109 | 10127 |
10110 | 10128 |
10111 Runtime::Function* Runtime::FunctionForName(Vector<const char> name) { | 10129 Runtime::Function* Runtime::FunctionForSymbol(Handle<String> name) { |
10112 for (Function* f = Runtime_functions; f->name != NULL; f++) { | 10130 int entry = Heap::intrinsic_function_names()->FindEntry(*name); |
10113 if (strncmp(f->name, name.start(), name.length()) == 0 | 10131 if (entry != kNotFound) { |
10114 && f->name[name.length()] == 0) { | 10132 Object* smi_index = Heap::intrinsic_function_names()->ValueAt(entry); |
10115 return f; | 10133 int function_index = Smi::cast(smi_index)->value(); |
10116 } | 10134 return &(kIntrinsicFunctions[function_index]); |
10117 } | 10135 } |
10118 return NULL; | 10136 return NULL; |
10119 } | 10137 } |
10120 | 10138 |
10121 | 10139 |
| 10140 Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
| 10141 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
| 10142 } |
| 10143 |
| 10144 |
10122 void Runtime::PerformGC(Object* result) { | 10145 void Runtime::PerformGC(Object* result) { |
10123 Failure* failure = Failure::cast(result); | 10146 Failure* failure = Failure::cast(result); |
10124 if (failure->IsRetryAfterGC()) { | 10147 if (failure->IsRetryAfterGC()) { |
10125 // Try to do a garbage collection; ignore it if it fails. The C | 10148 // Try to do a garbage collection; ignore it if it fails. The C |
10126 // entry stub will throw an out-of-memory exception in that case. | 10149 // entry stub will throw an out-of-memory exception in that case. |
10127 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); | 10150 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); |
10128 } else { | 10151 } else { |
10129 // Handle last resort GC and make sure to allow future allocations | 10152 // Handle last resort GC and make sure to allow future allocations |
10130 // to grow the heap without causing GCs (if possible). | 10153 // to grow the heap without causing GCs (if possible). |
10131 Counters::gc_last_resort_from_js.Increment(); | 10154 Counters::gc_last_resort_from_js.Increment(); |
10132 Heap::CollectAllGarbage(false); | 10155 Heap::CollectAllGarbage(false); |
10133 } | 10156 } |
10134 } | 10157 } |
10135 | 10158 |
10136 | 10159 |
10137 } } // namespace v8::internal | 10160 } } // namespace v8::internal |
OLD | NEW |