ic-compiler.cc 4.42 KB
Newer Older
1
// Copyright 2014 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5
#include "src/ic/ic-compiler.h"
6

7
#include "src/ic/handler-compiler.h"
8
#include "src/ic/ic-inl.h"
9

10 11
namespace v8 {
namespace internal {
12

13
Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
14
    Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
15 16 17 18 19 20 21
  Isolate* isolate = receiver_map->GetIsolate();

  DCHECK(store_mode == STANDARD_STORE ||
         store_mode == STORE_AND_GROW_NO_TRANSITION ||
         store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
         store_mode == STORE_NO_TRANSITION_HANDLE_COW);

22
  PropertyICCompiler compiler(isolate);
23 24 25 26 27 28 29
  Handle<Code> code =
      compiler.CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
  return code;
}

void PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
    MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
30
    CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
31 32 33 34 35
  Isolate* isolate = receiver_maps->at(0)->GetIsolate();
  DCHECK(store_mode == STANDARD_STORE ||
         store_mode == STORE_AND_GROW_NO_TRANSITION ||
         store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
         store_mode == STORE_NO_TRANSITION_HANDLE_COW);
36
  PropertyICCompiler compiler(isolate);
37 38 39 40 41 42 43 44
  compiler.CompileKeyedStorePolymorphicHandlers(
      receiver_maps, transitioned_maps, handlers, store_mode);
}


void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers(
    MapHandleList* receiver_maps, MapHandleList* transitioned_maps,
    CodeHandleList* handlers, KeyedAccessStoreMode store_mode) {
45 46 47
  for (int i = 0; i < receiver_maps->length(); ++i) {
    Handle<Map> receiver_map(receiver_maps->at(i));
    Handle<Code> cached_stub;
48 49 50 51 52
    Handle<Map> transitioned_map;
    {
      Map* tmap = receiver_map->FindElementsKindTransitionedMap(receiver_maps);
      if (tmap != nullptr) transitioned_map = handle(tmap);
    }
53 54 55 56 57 58 59

    // TODO(mvstanton): The code below is doing pessimistic elements
    // transitions. I would like to stop doing that and rely on Allocation Site
    // Tracking to do a better job of ensuring the data types are what they need
    // to be. Not all the elements are in place yet, pessimistic elements
    // transitions are still important for performance.
    if (!transitioned_map.is_null()) {
60 61 62 63
      bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
      ElementsKind elements_kind = receiver_map->elements_kind();
      TRACE_HANDLER_STATS(isolate(),
                          KeyedStoreIC_ElementsTransitionAndStoreStub);
64 65 66 67
      cached_stub =
          ElementsTransitionAndStoreStub(isolate(), elements_kind,
                                         transitioned_map->elements_kind(),
                                         is_js_array, store_mode).GetCode();
68
    } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
69 70
      // TODO(mvstanton): Consider embedding store_mode in the state of the slow
      // keyed store ic for uniformity.
71
      TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub);
72
      cached_stub = isolate()->builtins()->KeyedStoreIC_Slow();
73
    } else {
74 75
      cached_stub =
          CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode);
76
    }
77
    DCHECK(!cached_stub.is_null());
78 79
    handlers->Add(cached_stub);
    transitioned_maps->Add(transitioned_map);
80
  }
81 82 83
}


84 85 86
#define __ ACCESS_MASM(masm())


87
Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphicHandler(
88 89 90 91
    Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
  ElementsKind elements_kind = receiver_map->elements_kind();
  bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
  Handle<Code> stub;
92
  if (receiver_map->has_sloppy_arguments_elements()) {
93
    TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_KeyedStoreSloppyArgumentsStub);
94
    stub = KeyedStoreSloppyArgumentsStub(isolate(), store_mode).GetCode();
95 96
  } else if (receiver_map->has_fast_elements() ||
             receiver_map->has_fixed_typed_array_elements()) {
97
    TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub);
98 99 100
    stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind,
                                store_mode).GetCode();
  } else {
101
    TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
102
    stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode();
103
  }
104 105 106 107
  return stub;
}


108
#undef __
109 110
}  // namespace internal
}  // namespace v8