V8 Project
runtime-test.cc
Go to the documentation of this file.
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/v8.h"
6 
7 #include "src/arguments.h"
8 #include "src/deoptimizer.h"
9 #include "src/full-codegen.h"
10 #include "src/runtime/runtime.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
17  HandleScope scope(isolate);
18  DCHECK(args.length() == 1);
20  if (!function->IsOptimized()) return isolate->heap()->undefined_value();
21 
22  // TODO(turbofan): Deoptimization is not supported yet.
23  if (function->code()->is_turbofanned() && !FLAG_turbo_deoptimization) {
24  return isolate->heap()->undefined_value();
25  }
26 
28 
29  return isolate->heap()->undefined_value();
30 }
31 
32 
33 RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
34  SealHandleScope shs(isolate);
35  DCHECK(args.length() == 0);
36 #if defined(USE_SIMULATOR)
37  return isolate->heap()->true_value();
38 #else
39  return isolate->heap()->false_value();
40 #endif
41 }
42 
43 
44 RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
45  SealHandleScope shs(isolate);
46  DCHECK(args.length() == 0);
47  return isolate->heap()->ToBoolean(
48  isolate->concurrent_recompilation_enabled());
49 }
50 
51 
52 RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
53  HandleScope scope(isolate);
54  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
56  // The following two assertions are lifted from the DCHECKs inside
57  // JSFunction::MarkForOptimization().
58  RUNTIME_ASSERT(!function->shared()->is_generator());
59  RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() ||
60  (function->code()->kind() == Code::FUNCTION &&
61  function->code()->optimizable()));
62 
63  // If the function is optimized, just return.
64  if (function->IsOptimized()) return isolate->heap()->undefined_value();
65 
66  function->MarkForOptimization();
67 
68  Code* unoptimized = function->shared()->code();
69  if (args.length() == 2 && unoptimized->kind() == Code::FUNCTION) {
71  if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) {
72  // Start patching from the currently patched loop nesting level.
73  DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
74  isolate->runtime_profiler()->AttemptOnStackReplacement(
75  *function, Code::kMaxLoopNestingMarker);
76  } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
77  isolate->concurrent_recompilation_enabled()) {
78  function->MarkForConcurrentOptimization();
79  }
80  }
81 
82  return isolate->heap()->undefined_value();
83 }
84 
85 
86 RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
87  HandleScope scope(isolate);
88  DCHECK(args.length() == 1);
89  CONVERT_ARG_CHECKED(JSFunction, function, 0);
90  function->shared()->set_optimization_disabled(true);
91  return isolate->heap()->undefined_value();
92 }
93 
94 
95 RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
96  HandleScope scope(isolate);
97  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
98  if (!isolate->use_crankshaft()) {
99  return Smi::FromInt(4); // 4 == "never".
100  }
101  bool sync_with_compiler_thread = true;
102  if (args.length() == 2) {
104  if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR("no sync"))) {
105  sync_with_compiler_thread = false;
106  }
107  }
109  if (isolate->concurrent_recompilation_enabled() &&
110  sync_with_compiler_thread) {
111  while (function->IsInOptimizationQueue()) {
112  isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
113  base::OS::Sleep(50);
114  }
115  }
116  if (FLAG_always_opt) {
117  // We may have always opt, but that is more best-effort than a real
118  // promise, so we still say "no" if it is not optimized.
119  return function->IsOptimized() ? Smi::FromInt(3) // 3 == "always".
120  : Smi::FromInt(2); // 2 == "no".
121  }
122  if (FLAG_deopt_every_n_times) {
123  return Smi::FromInt(6); // 6 == "maybe deopted".
124  }
125  if (function->IsOptimized() && function->code()->is_turbofanned()) {
126  return Smi::FromInt(7); // 7 == "TurboFan compiler".
127  }
128  return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes".
129  : Smi::FromInt(2); // 2 == "no".
130 }
131 
132 
133 RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
134  DCHECK(args.length() == 0);
135  RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
136  RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
137  isolate->optimizing_compiler_thread()->Unblock();
138  return isolate->heap()->undefined_value();
139 }
140 
141 
142 RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
143  HandleScope scope(isolate);
144  DCHECK(args.length() == 1);
146  return Smi::FromInt(function->shared()->opt_count());
147 }
148 
149 
150 RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
151  HandleScope scope(isolate);
152  DCHECK(args.length() == 1);
154  function->shared()->ClearTypeFeedbackInfo();
155  Code* unoptimized = function->shared()->code();
156  if (unoptimized->kind() == Code::FUNCTION) {
157  unoptimized->ClearInlineCaches();
158  }
159  return isolate->heap()->undefined_value();
160 }
161 
162 
163 RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
164  HandleScope scope(isolate);
165  DCHECK(args.length() == 0);
166  isolate->heap()->NotifyContextDisposed();
167  return isolate->heap()->undefined_value();
168 }
169 
170 
171 RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
172  SealHandleScope shs(isolate);
173  DCHECK(args.length() == 2 || args.length() == 3);
174 #ifdef DEBUG
175  CONVERT_SMI_ARG_CHECKED(interval, 0);
176  CONVERT_SMI_ARG_CHECKED(timeout, 1);
177  isolate->heap()->set_allocation_timeout(timeout);
178  FLAG_gc_interval = interval;
179  if (args.length() == 3) {
180  // Enable/disable inline allocation if requested.
181  CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
182  if (inline_allocation) {
183  isolate->heap()->EnableInlineAllocation();
184  } else {
185  isolate->heap()->DisableInlineAllocation();
186  }
187  }
188 #endif
189  return isolate->heap()->undefined_value();
190 }
191 
192 
193 RUNTIME_FUNCTION(Runtime_DebugPrint) {
194  SealHandleScope shs(isolate);
195  DCHECK(args.length() == 1);
196 
197  OFStream os(stdout);
198 #ifdef DEBUG
199  if (args[0]->IsString()) {
200  // If we have a string, assume it's a code "marker"
201  // and print some interesting cpu debugging info.
202  JavaScriptFrameIterator it(isolate);
203  JavaScriptFrame* frame = it.frame();
204  os << "fp = " << frame->fp() << ", sp = " << frame->sp()
205  << ", caller_sp = " << frame->caller_sp() << ": ";
206  } else {
207  os << "DebugPrint: ";
208  }
209  args[0]->Print(os);
210  if (args[0]->IsHeapObject()) {
211  os << "\n";
212  HeapObject::cast(args[0])->map()->Print(os);
213  }
214 #else
215  // ShortPrint is available in release mode. Print is not.
216  os << Brief(args[0]);
217 #endif
218  os << endl;
219 
220  return args[0]; // return TOS
221 }
222 
223 
224 RUNTIME_FUNCTION(Runtime_DebugTrace) {
225  SealHandleScope shs(isolate);
226  DCHECK(args.length() == 0);
227  isolate->PrintStack(stdout);
228  return isolate->heap()->undefined_value();
229 }
230 
231 
232 // This will not allocate (flatten the string), but it may run
233 // very slowly for very deeply nested ConsStrings. For debugging use only.
234 RUNTIME_FUNCTION(Runtime_GlobalPrint) {
235  SealHandleScope shs(isolate);
236  DCHECK(args.length() == 1);
237 
238  CONVERT_ARG_CHECKED(String, string, 0);
240  StringCharacterStream stream(string, &op);
241  while (stream.HasMore()) {
242  uint16_t character = stream.GetNext();
243  PrintF("%c", character);
244  }
245  return string;
246 }
247 
248 
249 RUNTIME_FUNCTION(Runtime_SystemBreak) {
250  SealHandleScope shs(isolate);
251  DCHECK(args.length() == 0);
253  return isolate->heap()->undefined_value();
254 }
255 
256 
257 // Sets a v8 flag.
258 RUNTIME_FUNCTION(Runtime_SetFlags) {
259  SealHandleScope shs(isolate);
260  DCHECK(args.length() == 1);
261  CONVERT_ARG_CHECKED(String, arg, 0);
263  arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
265  return isolate->heap()->undefined_value();
266 }
267 
268 
269 RUNTIME_FUNCTION(Runtime_Abort) {
270  SealHandleScope shs(isolate);
271  DCHECK(args.length() == 1);
272  CONVERT_SMI_ARG_CHECKED(message_id, 0);
273  const char* message =
274  GetBailoutReason(static_cast<BailoutReason>(message_id));
275  base::OS::PrintError("abort: %s\n", message);
276  isolate->PrintStack(stderr);
277  base::OS::Abort();
278  UNREACHABLE();
279  return NULL;
280 }
281 
282 
283 RUNTIME_FUNCTION(Runtime_AbortJS) {
284  HandleScope scope(isolate);
285  DCHECK(args.length() == 1);
286  CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
287  base::OS::PrintError("abort: %s\n", message->ToCString().get());
288  isolate->PrintStack(stderr);
289  base::OS::Abort();
290  UNREACHABLE();
291  return NULL;
292 }
293 
294 
295 RUNTIME_FUNCTION(Runtime_HaveSameMap) {
296  SealHandleScope shs(isolate);
297  DCHECK(args.length() == 2);
298  CONVERT_ARG_CHECKED(JSObject, obj1, 0);
299  CONVERT_ARG_CHECKED(JSObject, obj2, 1);
300  return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
301 }
302 
303 
304 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
305  RUNTIME_FUNCTION(Runtime_Has##Name) { \
306  CONVERT_ARG_CHECKED(JSObject, obj, 0); \
307  return isolate->heap()->ToBoolean(obj->Has##Name()); \
308  }
309 
311 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
312 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
313 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
314 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
315 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
316 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
317 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
318 // Properties test sitting with elements tests - not fooling anyone.
320 
321 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
322 }
323 } // namespace v8::internal
static void Abort()
static void Sleep(const int milliseconds)
static void PrintError(const char *format,...)
static void DebugBreak()
void ClearInlineCaches()
Definition: objects.cc:10377
static const int kMaxLoopNestingMarker
Definition: objects.h:5346
static void DeoptimizeFunction(JSFunction *function)
Definition: deoptimizer.cc:503
static int SetFlagsFromString(const char *str, int len)
Definition: flags.cc:472
static Smi * FromInt(int value)
Definition: objects-inl.h:1321
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define UNREACHABLE()
Definition: logging.h:30
#define DCHECK(condition)
Definition: logging.h:205
unsigned short uint16_t
Definition: unicode.cc:23
@ DISALLOW_NULLS
Definition: objects.h:8337
OStream & endl(OStream &os)
Definition: ostreams.cc:112
@ ROBUST_STRING_TRAVERSAL
Definition: objects.h:8338
const char * GetBailoutReason(BailoutReason reason)
void PrintF(const char *format,...)
Definition: utils.cc:80
int StrLength(const char *string)
Definition: vector.h:147
@ RUNTIME_FUNCTION
Definition: serialize.h:23
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)
#define CONVERT_BOOLEAN_ARG_CHECKED(name, index)
Definition: runtime-utils.h:39
#define CONVERT_ARG_CHECKED(Type, name, index)
Definition: runtime-utils.h:24
#define RUNTIME_ASSERT(value)
Definition: runtime-utils.h:12
#define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)
Definition: runtime-utils.h:28
#define CONVERT_SMI_ARG_CHECKED(name, index)
Definition: runtime-utils.h:46
#define STATIC_CHAR_VECTOR(x)
Definition: vector.h:154