OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 | 311 |
312 // static | 312 // static |
313 void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime( | 313 void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime( |
314 Isolate* isolate, const BinaryOpICState& state) { | 314 Isolate* isolate, const BinaryOpICState& state) { |
315 if (state.CouldCreateAllocationMementos()) { | 315 if (state.CouldCreateAllocationMementos()) { |
316 BinaryOpICWithAllocationSiteStub stub(isolate, state); | 316 BinaryOpICWithAllocationSiteStub stub(isolate, state); |
317 stub.GetCode(); | 317 stub.GetCode(); |
318 } | 318 } |
319 } | 319 } |
320 | 320 |
321 | |
322 std::ostream& operator<<(std::ostream& os, const StringAddFlags& flags) { | |
323 switch (flags) { | |
324 case STRING_ADD_CHECK_NONE: | |
325 return os << "CheckNone"; | |
326 case STRING_ADD_CHECK_LEFT: | |
327 return os << "CheckLeft"; | |
328 case STRING_ADD_CHECK_RIGHT: | |
329 return os << "CheckRight"; | |
330 case STRING_ADD_CHECK_BOTH: | |
331 return os << "CheckBoth"; | |
332 case STRING_ADD_CONVERT_LEFT: | |
333 return os << "ConvertLeft"; | |
334 case STRING_ADD_CONVERT_RIGHT: | |
335 return os << "ConvertRight"; | |
336 case STRING_ADD_CONVERT: | |
337 break; | |
338 } | |
339 UNREACHABLE(); | |
340 return os; | |
341 } | |
342 | |
343 | |
344 void StringAddStub::PrintBaseName(std::ostream& os) const { // NOLINT | 321 void StringAddStub::PrintBaseName(std::ostream& os) const { // NOLINT |
345 os << "StringAddStub_" << flags() << "_" << pretenure_flag(); | 322 os << "StringAddStub_" << flags() << "_" << pretenure_flag(); |
346 } | 323 } |
347 | 324 |
348 void StringAddStub::GenerateAssembly(CodeStubAssembler* assembler) const { | 325 void StringAddStub::GenerateAssembly(CodeStubAssembler* assembler) const { |
349 typedef compiler::Node Node; | 326 typedef compiler::Node Node; |
350 Node* left = assembler->Parameter(Descriptor::kLeft); | 327 Node* left = assembler->Parameter(Descriptor::kLeft); |
351 Node* right = assembler->Parameter(Descriptor::kRight); | 328 Node* right = assembler->Parameter(Descriptor::kRight); |
352 Node* context = assembler->Parameter(Descriptor::kContext); | 329 Node* context = assembler->Parameter(Descriptor::kContext); |
353 | 330 |
(...skipping 1996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2350 // Note: Although a no-op transition is semantically OK, it is hinting at a | 2327 // Note: Although a no-op transition is semantically OK, it is hinting at a |
2351 // bug somewhere in our state transition machinery. | 2328 // bug somewhere in our state transition machinery. |
2352 DCHECK(from != to); | 2329 DCHECK(from != to); |
2353 if (!FLAG_trace_ic) return; | 2330 if (!FLAG_trace_ic) return; |
2354 OFStream os(stdout); | 2331 OFStream os(stdout); |
2355 os << "["; | 2332 os << "["; |
2356 PrintBaseName(os); | 2333 PrintBaseName(os); |
2357 os << ": " << from << "=>" << to << "]" << std::endl; | 2334 os << ": " << from << "=>" << to << "]" << std::endl; |
2358 } | 2335 } |
2359 | 2336 |
2360 | |
2361 // TODO(svenpanne) Make this a real infix_ostream_iterator. | |
2362 class SimpleListPrinter { | |
2363 public: | |
2364 explicit SimpleListPrinter(std::ostream& os) : os_(os), first_(true) {} | |
2365 | |
2366 void Add(const char* s) { | |
2367 if (first_) { | |
2368 first_ = false; | |
2369 } else { | |
2370 os_ << ","; | |
2371 } | |
2372 os_ << s; | |
2373 } | |
2374 | |
2375 private: | |
2376 std::ostream& os_; | |
2377 bool first_; | |
2378 }; | |
2379 | |
2380 | |
2381 void CallICStub::PrintState(std::ostream& os) const { // NOLINT | 2337 void CallICStub::PrintState(std::ostream& os) const { // NOLINT |
2382 os << state(); | 2338 os << state(); |
2383 } | 2339 } |
2384 | 2340 |
2385 | 2341 |
2386 void JSEntryStub::FinishCode(Handle<Code> code) { | 2342 void JSEntryStub::FinishCode(Handle<Code> code) { |
2387 Handle<FixedArray> handler_table = | 2343 Handle<FixedArray> handler_table = |
2388 code->GetIsolate()->factory()->NewFixedArray(1, TENURED); | 2344 code->GetIsolate()->factory()->NewFixedArray(1, TENURED); |
2389 handler_table->set(0, Smi::FromInt(handler_offset_)); | 2345 handler_table->set(0, Smi::FromInt(handler_offset_)); |
2390 code->set_handler_table(*handler_table); | 2346 code->set_handler_table(*handler_table); |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3036 STORE_AND_GROW_NO_TRANSITION).GetCode(); | 2992 STORE_AND_GROW_NO_TRANSITION).GetCode(); |
3037 for (int i = FIRST_FAST_ELEMENTS_KIND; i <= LAST_FAST_ELEMENTS_KIND; i++) { | 2993 for (int i = FIRST_FAST_ELEMENTS_KIND; i <= LAST_FAST_ELEMENTS_KIND; i++) { |
3038 ElementsKind kind = static_cast<ElementsKind>(i); | 2994 ElementsKind kind = static_cast<ElementsKind>(i); |
3039 StoreFastElementStub(isolate, true, kind, STANDARD_STORE).GetCode(); | 2995 StoreFastElementStub(isolate, true, kind, STANDARD_STORE).GetCode(); |
3040 StoreFastElementStub(isolate, true, kind, STORE_AND_GROW_NO_TRANSITION) | 2996 StoreFastElementStub(isolate, true, kind, STORE_AND_GROW_NO_TRANSITION) |
3041 .GetCode(); | 2997 .GetCode(); |
3042 } | 2998 } |
3043 } | 2999 } |
3044 | 3000 |
3045 bool ToBooleanICStub::UpdateStatus(Handle<Object> object) { | 3001 bool ToBooleanICStub::UpdateStatus(Handle<Object> object) { |
3046 Types new_types = types(); | 3002 ToBooleanHints old_hints = hints(); |
3047 Types old_types = new_types; | 3003 ToBooleanHints new_hints = old_hints; |
3048 bool to_boolean_value = new_types.UpdateStatus(isolate(), object); | 3004 bool to_boolean_value = false; // Dummy initialization. |
3049 TraceTransition(old_types, new_types); | 3005 if (object->IsUndefined(isolate())) { |
3050 set_sub_minor_key(TypesBits::update(sub_minor_key(), new_types.ToIntegral())); | 3006 new_hints |= ToBooleanHint::kUndefined; |
| 3007 to_boolean_value = false; |
| 3008 } else if (object->IsBoolean()) { |
| 3009 new_hints |= ToBooleanHint::kBoolean; |
| 3010 to_boolean_value = object->IsTrue(isolate()); |
| 3011 } else if (object->IsNull(isolate())) { |
| 3012 new_hints |= ToBooleanHint::kNull; |
| 3013 to_boolean_value = false; |
| 3014 } else if (object->IsSmi()) { |
| 3015 new_hints |= ToBooleanHint::kSmallInteger; |
| 3016 to_boolean_value = Smi::cast(*object)->value() != 0; |
| 3017 } else if (object->IsJSReceiver()) { |
| 3018 new_hints |= ToBooleanHint::kReceiver; |
| 3019 to_boolean_value = !object->IsUndetectable(); |
| 3020 } else if (object->IsString()) { |
| 3021 DCHECK(!object->IsUndetectable()); |
| 3022 new_hints |= ToBooleanHint::kString; |
| 3023 to_boolean_value = String::cast(*object)->length() != 0; |
| 3024 } else if (object->IsSymbol()) { |
| 3025 new_hints |= ToBooleanHint::kSymbol; |
| 3026 to_boolean_value = true; |
| 3027 } else if (object->IsHeapNumber()) { |
| 3028 DCHECK(!object->IsUndetectable()); |
| 3029 new_hints |= ToBooleanHint::kHeapNumber; |
| 3030 double value = HeapNumber::cast(*object)->value(); |
| 3031 to_boolean_value = value != 0 && !std::isnan(value); |
| 3032 } else if (object->IsSimd128Value()) { |
| 3033 new_hints |= ToBooleanHint::kSimdValue; |
| 3034 to_boolean_value = true; |
| 3035 } else { |
| 3036 // We should never see an internal object at runtime here! |
| 3037 UNREACHABLE(); |
| 3038 to_boolean_value = true; |
| 3039 } |
| 3040 TraceTransition(old_hints, new_hints); |
| 3041 set_sub_minor_key(HintsBits::update(sub_minor_key(), new_hints)); |
3051 return to_boolean_value; | 3042 return to_boolean_value; |
3052 } | 3043 } |
3053 | 3044 |
3054 void ToBooleanICStub::PrintState(std::ostream& os) const { // NOLINT | 3045 void ToBooleanICStub::PrintState(std::ostream& os) const { // NOLINT |
3055 os << types(); | 3046 os << hints(); |
3056 } | 3047 } |
3057 | 3048 |
3058 std::ostream& operator<<(std::ostream& os, const ToBooleanICStub::Types& s) { | |
3059 os << "("; | |
3060 SimpleListPrinter p(os); | |
3061 if (s.IsEmpty()) p.Add("None"); | |
3062 if (s.Contains(ToBooleanICStub::UNDEFINED)) p.Add("Undefined"); | |
3063 if (s.Contains(ToBooleanICStub::BOOLEAN)) p.Add("Bool"); | |
3064 if (s.Contains(ToBooleanICStub::NULL_TYPE)) p.Add("Null"); | |
3065 if (s.Contains(ToBooleanICStub::SMI)) p.Add("Smi"); | |
3066 if (s.Contains(ToBooleanICStub::SPEC_OBJECT)) p.Add("SpecObject"); | |
3067 if (s.Contains(ToBooleanICStub::STRING)) p.Add("String"); | |
3068 if (s.Contains(ToBooleanICStub::SYMBOL)) p.Add("Symbol"); | |
3069 if (s.Contains(ToBooleanICStub::HEAP_NUMBER)) p.Add("HeapNumber"); | |
3070 if (s.Contains(ToBooleanICStub::SIMD_VALUE)) p.Add("SimdValue"); | |
3071 return os << ")"; | |
3072 } | |
3073 | |
3074 bool ToBooleanICStub::Types::UpdateStatus(Isolate* isolate, | |
3075 Handle<Object> object) { | |
3076 if (object->IsUndefined(isolate)) { | |
3077 Add(UNDEFINED); | |
3078 return false; | |
3079 } else if (object->IsBoolean()) { | |
3080 Add(BOOLEAN); | |
3081 return object->IsTrue(isolate); | |
3082 } else if (object->IsNull(isolate)) { | |
3083 Add(NULL_TYPE); | |
3084 return false; | |
3085 } else if (object->IsSmi()) { | |
3086 Add(SMI); | |
3087 return Smi::cast(*object)->value() != 0; | |
3088 } else if (object->IsJSReceiver()) { | |
3089 Add(SPEC_OBJECT); | |
3090 return !object->IsUndetectable(); | |
3091 } else if (object->IsString()) { | |
3092 DCHECK(!object->IsUndetectable()); | |
3093 Add(STRING); | |
3094 return String::cast(*object)->length() != 0; | |
3095 } else if (object->IsSymbol()) { | |
3096 Add(SYMBOL); | |
3097 return true; | |
3098 } else if (object->IsHeapNumber()) { | |
3099 DCHECK(!object->IsUndetectable()); | |
3100 Add(HEAP_NUMBER); | |
3101 double value = HeapNumber::cast(*object)->value(); | |
3102 return value != 0 && !std::isnan(value); | |
3103 } else if (object->IsSimd128Value()) { | |
3104 Add(SIMD_VALUE); | |
3105 return true; | |
3106 } else { | |
3107 // We should never see an internal object at runtime here! | |
3108 UNREACHABLE(); | |
3109 return true; | |
3110 } | |
3111 } | |
3112 | |
3113 bool ToBooleanICStub::Types::NeedsMap() const { | |
3114 return Contains(ToBooleanICStub::SPEC_OBJECT) || | |
3115 Contains(ToBooleanICStub::STRING) || | |
3116 Contains(ToBooleanICStub::SYMBOL) || | |
3117 Contains(ToBooleanICStub::HEAP_NUMBER) || | |
3118 Contains(ToBooleanICStub::SIMD_VALUE); | |
3119 } | |
3120 | |
3121 | |
3122 void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) { | 3049 void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) { |
3123 StubFailureTrampolineStub stub1(isolate, NOT_JS_FUNCTION_STUB_MODE); | 3050 StubFailureTrampolineStub stub1(isolate, NOT_JS_FUNCTION_STUB_MODE); |
3124 StubFailureTrampolineStub stub2(isolate, JS_FUNCTION_STUB_MODE); | 3051 StubFailureTrampolineStub stub2(isolate, JS_FUNCTION_STUB_MODE); |
3125 stub1.GetCode(); | 3052 stub1.GetCode(); |
3126 stub2.GetCode(); | 3053 stub2.GetCode(); |
3127 } | 3054 } |
3128 | 3055 |
3129 | 3056 |
3130 void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function, | 3057 void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function, |
3131 intptr_t stack_pointer, | 3058 intptr_t stack_pointer, |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3304 assembler->Return(assembler->CallRuntime(Runtime::kGrowArrayElements, context, | 3231 assembler->Return(assembler->CallRuntime(Runtime::kGrowArrayElements, context, |
3305 object, key)); | 3232 object, key)); |
3306 } | 3233 } |
3307 | 3234 |
3308 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate) | 3235 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate) |
3309 : PlatformCodeStub(isolate) {} | 3236 : PlatformCodeStub(isolate) {} |
3310 | 3237 |
3311 InternalArrayConstructorStub::InternalArrayConstructorStub(Isolate* isolate) | 3238 InternalArrayConstructorStub::InternalArrayConstructorStub(Isolate* isolate) |
3312 : PlatformCodeStub(isolate) {} | 3239 : PlatformCodeStub(isolate) {} |
3313 | 3240 |
3314 Representation RepresentationFromMachineType(MachineType type) { | |
3315 if (type == MachineType::Int32()) { | |
3316 return Representation::Integer32(); | |
3317 } | |
3318 | |
3319 if (type == MachineType::TaggedSigned()) { | |
3320 return Representation::Smi(); | |
3321 } | |
3322 | |
3323 if (type == MachineType::Pointer()) { | |
3324 return Representation::External(); | |
3325 } | |
3326 | |
3327 return Representation::Tagged(); | |
3328 } | |
3329 | |
3330 } // namespace internal | 3241 } // namespace internal |
3331 } // namespace v8 | 3242 } // namespace v8 |
OLD | NEW |